Qt 小部件不接收 keyPressEvent
Qt widget does not receive keyPressEvent
我的子小部件没有获取 keyPressEvents,而如果我将相同的小部件放置在顶层 window,它就会获取。我尝试将其设置为获得焦点,但对此没有任何影响。代码在下面,显示了我尝试开始工作的内容。
#include <QApplication>
#include <QKeyEvent>
#include <QLCDNumber>
#include <QLabel>
#include <QVBoxLayout>
class DigitSummer: public QLCDNumber {
Q_OBJECT
public:
DigitSummer(QWidget *parent = nullptr) : QLCDNumber(parent) {
}
protected:
void keyPressEvent(QKeyEvent *event) override {
display(intValue() + event->text().toInt());
}
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
#if 1 // this version does not work, number does not increase
QWidget widget;
widget.setLayout(new QVBoxLayout());
widget.layout()->addWidget(new QLabel("Press digits!"));
DigitSummer summer; // in stack: must be after widget to avoid child delete
widget.layout()->addWidget(&summer);
widget.setFocusProxy(&summer); // I notice no effect!
widget.show();
#else // this version works, number grows with keypresseas
DigitSummer summer;
summer.show();
#endif
return a.exec();
}
#include "main.moc"
对于完整的 .pro 文件:
QT += core gui widgets
TARGET = QtMCVE
TEMPLATE = app
DEFINES += QT_DEPRECATED_WARNINGS
CONFIG += c++11
QMAKE_CXXFLAGS += -Wall -Wextra
SOURCES += main.cpp
如何修复小部件接收按键事件?
This related question 建议安装事件过滤器,但我不想那样做,必须有一种自包含的方法来修复小部件本身。
我认为您需要为小部件设置 focus policy 才能接受键盘输入。在你的 ctor 中尝试...
setFocusPolicy(Qt::StrongFocus);
话虽如此,我真的不确定为什么 top-level 和非 top-level 小部件的行为会有所不同。
问题代码的工作版本:
#include <QApplication>
#include <QKeyEvent>
#include <QLCDNumber>
#include <QLabel>
#include <QVBoxLayout>
class DigitSummer: public QLCDNumber {
Q_OBJECT
public:
DigitSummer(QWidget *parent = nullptr) : QLCDNumber(parent) {
setFocusPolicy(Qt::StrongFocus);
}
protected:
void keyPressEvent(QKeyEvent *event) override {
display(intValue() + event->text().toInt());
}
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QWidget widget;
widget.setLayout(new QVBoxLayout());
widget.layout()->addWidget(new QLabel("Press digits!"));
widget.layout()->addWidget(new DigitSummer);
widget.show();
return a.exec();
}
#include "main.moc"
我的子小部件没有获取 keyPressEvents,而如果我将相同的小部件放置在顶层 window,它就会获取。我尝试将其设置为获得焦点,但对此没有任何影响。代码在下面,显示了我尝试开始工作的内容。
#include <QApplication>
#include <QKeyEvent>
#include <QLCDNumber>
#include <QLabel>
#include <QVBoxLayout>
class DigitSummer: public QLCDNumber {
Q_OBJECT
public:
DigitSummer(QWidget *parent = nullptr) : QLCDNumber(parent) {
}
protected:
void keyPressEvent(QKeyEvent *event) override {
display(intValue() + event->text().toInt());
}
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
#if 1 // this version does not work, number does not increase
QWidget widget;
widget.setLayout(new QVBoxLayout());
widget.layout()->addWidget(new QLabel("Press digits!"));
DigitSummer summer; // in stack: must be after widget to avoid child delete
widget.layout()->addWidget(&summer);
widget.setFocusProxy(&summer); // I notice no effect!
widget.show();
#else // this version works, number grows with keypresseas
DigitSummer summer;
summer.show();
#endif
return a.exec();
}
#include "main.moc"
对于完整的 .pro 文件:
QT += core gui widgets
TARGET = QtMCVE
TEMPLATE = app
DEFINES += QT_DEPRECATED_WARNINGS
CONFIG += c++11
QMAKE_CXXFLAGS += -Wall -Wextra
SOURCES += main.cpp
如何修复小部件接收按键事件?
This related question 建议安装事件过滤器,但我不想那样做,必须有一种自包含的方法来修复小部件本身。
我认为您需要为小部件设置 focus policy 才能接受键盘输入。在你的 ctor 中尝试...
setFocusPolicy(Qt::StrongFocus);
话虽如此,我真的不确定为什么 top-level 和非 top-level 小部件的行为会有所不同。
问题代码的工作版本:
#include <QApplication>
#include <QKeyEvent>
#include <QLCDNumber>
#include <QLabel>
#include <QVBoxLayout>
class DigitSummer: public QLCDNumber {
Q_OBJECT
public:
DigitSummer(QWidget *parent = nullptr) : QLCDNumber(parent) {
setFocusPolicy(Qt::StrongFocus);
}
protected:
void keyPressEvent(QKeyEvent *event) override {
display(intValue() + event->text().toInt());
}
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QWidget widget;
widget.setLayout(new QVBoxLayout());
widget.layout()->addWidget(new QLabel("Press digits!"));
widget.layout()->addWidget(new DigitSummer);
widget.show();
return a.exec();
}
#include "main.moc"