QWidget keyPressEvent覆盖

Eri*_*ner 19 c++ qt overriding virtual-functions

我正在尝试半个永恒现在覆盖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);
};
Run Code Online (Sandbox Code Playgroud)

QSGameBoard是我的QWidget子类,我需要覆盖keyPressEvent并在每个事件上触发SIGNAL以通知一些注册的对象.

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

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

当我将QSGameBoard ::更改为QWidget ::它接收事件,但我无法发出信号,因为编译器抱怨范围.如果我像这样写它,函数根本不会被调用.

这有什么问题?

Gay*_*yan 14

编辑:正如其他用户所指出的,我最初概述的方法不是解决此问题的正确方法.通过回答Vasco Rinaldo

使用将FocusPolicy设置为Qt :: ClickFocus以通过鼠标klick获取keybordfocus.setFocusPolicy(QT :: ClickFocus);

我给出的先前(虽然不完美)的解决方案如下:

看起来你的小部件没有"焦点".覆盖鼠标按下事件:

void QSGameBoard::mousePressEvent ( QMouseEvent * event ){
    printf("\nMouse in board");
    setFocus();
}
Run Code Online (Sandbox Code Playgroud)

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

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 */
Run Code Online (Sandbox Code Playgroud)

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();
}
Run Code Online (Sandbox Code Playgroud)

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();
}
Run Code Online (Sandbox Code Playgroud)


squ*_*uid 12

您不必为了调用setFocus而自己重新实现mousePressEvent.Qt已经计划好了.

设置FocusPolicyto Qt::ClickFocus以通过鼠标klick获取keybordfocus.

setFocusPolicy(QT :: ClickFocus);

如手册中所述:

此属性保持窗口小部件接受键盘焦点的方式.

如果小部件通过Tab键接受键盘焦点,则策略为Qt :: TabFocus;如果小部件通过单击接受焦点,则为Qt :: ClickFocus;如果接受两者,则为Qt :: StrongFocus;如果不接受,则为Qt :: NoFocus(默认值)完全接受焦点.

如果处理键盘事件,则必须为窗口小部件启用键盘焦点.这通常是从小部件的构造函数完成的.例如,QLineEdit构造函数调用setFocusPolicy(Qt :: StrongFocus).

如果窗口小部件具有焦点代理,则焦点策略将传播到它.


Vas*_*ldo 8

将FocusPolicy设置为Qt :: ClickFocus以通过鼠标klick获取keybordfocus.setFocusPolicy(QT :: ClickFocus);