【问题标题】:Qt widget does not receive keyPressEventQt 小部件没有收到 keyPressEvent
【发布时间】:2019-05-08 15:43:30
【问题描述】:

我的子小部件没有获得 keyPressEvents,而如果我将相同的小部件放置在顶级窗口中,它会获得。我尝试将其设置为焦点,但这对此没有影响。代码如下,显示了我尝试工作的内容。

#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 建议安装事件过滤器,但我不想这样做,必须有一个独立的方法来修复小部件本身。

【问题讨论】:

    标签: qt qwidget qkeyevent


    【解决方案1】:

    我认为您需要为小部件设置focus policy,然后它才能接受键盘输入。在您的 ctor 中尝试...

    setFocusPolicy(Qt::StrongFocus);
    

    话虽如此,我真的不确定为什么顶级和非顶级小部件的行为会有所不同。


    问题代码的工作版本:

    #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"
    

    【讨论】:

    • 确实如此。将 widget.setFocusPolicy(Qt::StringFocus); 添加到 main 函数也可以修复它,但正确的解决方案是将其添加到 DigitSummer 构造函数,并且根本不会混淆 main 中的焦点。我想我会用正确的代码编辑你的答案。
    • @hyde 我的回答确实声明了"In your ctor try...",所以这就是意图。还是我误解了你的评论?
    • 我只是想说为widget 设置focusPolicy focusProxy 也可以,但它(在大多数情况下)不是正确的解决方案,最好是确实在 DigitSummer 构造函数中做到这一点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-10
    • 2017-02-14
    • 2019-07-15
    • 1970-01-01
    • 2021-12-03
    相关资源
    最近更新 更多