除了使用tab键切换输入焦点外,如果希望通过其他按键也可以达到tab键同样的效果。该如何做呢?
重写keyPressEvent
有一个对话框,由一些QLineEdit控件组成。我们希望按下Space键得到下一个QLineEdit的输入焦点。一个直接的方法是继承QLineEdit,重写keyPressEvent()函数。当点击了Space键时,调用focusNextChild()
void QtEventFilterTest::keyPressEvent(QKeyEvent *event)
{
if (event->key() == Qt::Key_Space) {
focusNextChild();
}
else {
QLineEdit::keyPressEvent(event);
}
}
这个方法有一个最大的缺点:如果窗体中使用了很多不同类型的控件(如QComboBox,QSpinBox等),我们也要继承这些控件,重写它们的keyPressEvent()。
使用 eventFilter
一个更好的解决方法:通过事件过滤的方法,监视子控件的键盘事件,在监视代码处实现以上功能。
实现一个事件过滤包括两个步骤:
1、在目标对象上调用installEventFilter(),注册监视对象。
2、在监视对象的eventFilter()函数中处理目标对象的事件。
示例代码如下:
#include "QtEventFilterTest.h"
#include <QVBoxLayout>
#include <QLineEdit>
#include <QKeyEvent>
#include <QComboBox>
QtEventFilterTest::QtEventFilterTest(QWidget *parent)
: QDialog(parent)
{
setFixedSize(400, 200);
QVBoxLayout * layout = new QVBoxLayout();
layout->setContentsMargins(15, 10, 15, 10);
editUserName = new QLineEdit("username");
layout->addWidget(editUserName);
editPassword = new QLineEdit("password");
layout->addWidget(editPassword);
comboSex = new QComboBox();
layout->addWidget(comboSex);
comboSex->addItems({ "boy", "girl" });
editPhone = new QLineEdit("phone");
layout->addWidget(editPhone);
setLayout(layout);
//注册监视对象
editUserName->installEventFilter(this);
editPassword->installEventFilter(this);
editPhone->installEventFilter(this);
comboSex->installEventFilter(this);
}
//
bool QtEventFilterTest::eventFilter(QObject *target, QEvent *event)
{
if (target == editUserName
|| target == editPassword
|| target == editPhone
|| target == comboSex)
{
if (event->type() == QEvent::KeyPress)
{
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
if (keyEvent->key() == Qt::Key_Return)
{
focusNextChild();
return true;
}
}
}
return QDialog::eventFilter(target, event);
}