【问题标题】:QWidget keyPressEvent overrideQWidget keyPressEvent 覆盖
【发布时间】:2011-02-13 14:08:35
【问题描述】:

我正在尝试在 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 并在每个事件上触发一个 SIGNAL 以通知一些已注册的对象。

我在 QSGameBoard.cpp 中覆盖的 keyPressEvent 如下所示:

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

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

这里有什么问题?

【问题讨论】:

  • 你接受了错误的答案。

标签: c++ qt virtual-functions overriding


【解决方案1】:

编辑: 正如其他用户所指出的,我最初概述的方法不是解决此问题的正确方法。 瓦斯科·里纳尔多

的回答

使用 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();
}

【讨论】:

  • 错误答案。下面的答案(由 squid 和 Vasco Rinaldo 提供)是正确的。
【解决方案2】:

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

FocusPolicy 设置为Qt::ClickFocus 以通过鼠标单击获得键盘焦点。

setFocusPolicy(Qt::ClickFocus);

如手册所述:

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

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

如果小部件处理键盘事件,您必须为它启用键盘焦点。这通常由小部件的构造函数完成。例如,QLineEdit 构造函数调用 setFocusPolicy(Qt::StrongFocus)。

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

【讨论】:

    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 2016-11-25
      • 2015-12-27
      • 1970-01-01
      • 1970-01-01
      • 2011-12-14
      • 2011-05-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多