QWidget keyPressEvent重载

20

我现在已经尝试了半个世纪,试图在QT中覆盖QWidgets keyPressEvent函数,但它就是不起作用。我必须说我是CPP的新手,但我懂ObjC和标准C。

我的问题看起来像这样:

class QSGameBoard : public QWidget {
Q_OBJECT

public:
  QSGameBoard(QWidget *p, int w, int h, QGraphicsScene *s);

signals:
  void keyCaught(QKeyEvent *e);

protected:
  virtual void  keyPressEvent(QKeyEvent *event);
};

QSGameBoard是我的QWidget子类,我需要重写keyPressEvent并在每个事件上发出信号,以通知一些已注册的对象。

在QSGameBoard.cpp中,我的重写的keyPressEvent如下:

void QSGameBoard::keyPressEvent(QKeyEvent *event) {
  printf("\nkey event in board: %i", event->key());
  //emit keyCaught(event);
}

将 QSGameBoard:: 改为 QWidget:: 后,可以接收事件,但由于作用域问题,无法发出信号。如果按照这种方式编写,函数根本不会被调用。

这里的问题是什么?


你选择了错误的答案。 - Johan Råde
3个回答

13

编辑: 正如其他用户所指出的,我最初提供的方法不是解决此问题的正确方式。 答案来自 Vasco Rinaldo

使用 Set the FocusPolicy to Qt::ClickFocus 以通过鼠标单击获取键盘焦点。setFocusPolicy(Qt::ClickFocus);

我之前给出的(尽管不完美)解决方案如下:

看起来你的小部件没有“焦点”。重写你的鼠标按下事件:

void QSGameBoard::mousePressEvent ( QMouseEvent * event ){
    printf("\nMouse in board");
    setFocus();
}

以下是一个可工作示例的源代码:

QSGameBoard.h

#ifndef _QSGAMEBOARD_H
#define _QSGAMEBOARD_H

#include <QWidget>
#include <QGraphicsScene>

class QSGameBoard : public QWidget {
Q_OBJECT

public:
  QSGameBoard(QWidget *p, int w, int h, QGraphicsScene *s);

signals:
  void keyCaught(QKeyEvent *e);

protected:
  virtual void  keyPressEvent(QKeyEvent *event);
  void  mousePressEvent ( QMouseEvent * event );
};


#endif  /* _QSGAMEBOARD_H */

QSGameBoard.cpp

#include <QKeyEvent>
#include <QLabel>
#include <QtGui/qgridlayout.h>
#include <QGridLayout>

#include "QSGameBoard.h"


QSGameBoard::QSGameBoard(QWidget* p, int w, int h, QGraphicsScene* s) :
    QWidget(p){

    QLabel* o = new QLabel(tr("Test Test Test"));
    QGridLayout* g  = new QGridLayout(this);
    g->addWidget(o);
}

void QSGameBoard::keyPressEvent(QKeyEvent* event){
    printf("\nkey event in board: %i", event->key());
}

void QSGameBoard::mousePressEvent ( QMouseEvent * event ){
    printf("\nMouse in board");
    setFocus();
}

主函数文件名为 main.cpp。

#include <QtGui/QApplication>
#include <QtGui/qmainwindow.h>

#include "QSGameBoard.h"

int main(int argc, char *argv[]) {
    // initialize resources, if needed
    // Q_INIT_RESOURCE(resfile);

    QApplication app(argc, argv);

    QMainWindow oM;
    QGraphicsScene o;
    QSGameBoard a(&oM, 1, 2, &o);
    oM.setCentralWidget(&a);
    a.show();
    oM.show();

    // create and show your widgets here

    return app.exec();
}

12

您不必重新实现mousePressEvent以调用setFocus。Qt已经计划好了。

FocusPolicy设置为Qt::ClickFocus即可通过鼠标点击获取键盘焦点。

setFocusPolicy(Qt::ClickFocus);

如手册所述:

此属性保存小部件接受键盘焦点的方式。

如果小部件通过制表符接受键盘焦点,则策略为Qt::TabFocus;如果小部件通过单击接受焦点,则策略为Qt::ClickFocus;如果它同时接受两者,则策略为Qt::StrongFocus;如果它根本不接受焦点,则策略为Qt::NoFocus(默认值)。

如果小部件处理键盘事件,则必须为其启用键盘焦点。通常是在小部件的构造函数中完成此操作。例如,QLineEdit构造函数调用setFocusPolicy(Qt::StrongFocus)。

如果小部件有一个焦点代理,则焦点策略将传播到它。


8

将 FocusPolicy 设置为 Qt::ClickFocus,通过鼠标单击获得键盘焦点。 setFocusPolicy(Qt::ClickFocus);


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接