1 Вопрос: Виджет Qt не получает keyPressEvent

вопрос создан в Wed, May 8, 2019 12:00 AM

Мой дочерний виджет не получает 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

Как исправить виджет для получения ключевых событий?

Этот связанный вопрос предлагает установить фильтр событий, но Я не хочу этого делать, должен быть автономный способ исправить сам виджет.

    
0
1 ответ                              1                         

Я думаю, вам нужно установить политику фокусировки для виджета, прежде чем он примет ввод с клавиатуры. В вашем 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"
    
1
2019-05-10 11: 56: 50Z
  1. Действительно. Добавление widget.setFocusPolicy(Qt::StringFocus); в основную функцию также исправляет это, но правильное решение состоит в том, чтобы добавить его в конструктор DigitSummer и вообще не мешать фокусу в главном. Я думаю, что я отредактирую ваш ответ с правильным кодом.
    2019-05-10 11: 54: 18Z
  2. @ hyde В моем ответе действительно указано "In your ctor try...", так что это было намерение. Или я неправильно понял ваш комментарий?
    2019-05-10 11: 56: 55Z
  3. Я просто хотел сказать, что настройка focusPolicy и focusProxy для widget тоже работает, но это (в большинстве сценариев) не будет правильным Решение, лучше сделать это в конструкторе DigitSummer.
    2019-05-10 11: 58: 52Z
источник размещен Вот