QWidget keyPressEvent 覆盖

发布于 2024-08-31 01:18:46 字数 759 浏览 6 评论 0原文

我已经尝试了半个世纪来覆盖 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:: 时,它接收事件,但我无法发出信号,因为编译器抱怨范围。如果我这样写,该函数根本不会被调用。

这里有什么问题?

I'm trying for half an eternity now overriding QWidgets keyPressEvent function in QT but it just won't work. I've to say i am new to CPP, but I know ObjC and standard C.

My problem looks like this:

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 is my QWidget subclass and i need to override the keyPressEvent and fire a SIGNAL on each event to notify some registered objects.

My overridden keyPressEvent in QSGameBoard.cpp looks like this:

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

When i change QSGameBoard:: to QWidget:: it receives the events, but i cant emit the signal because the compiler complains about the scope. And if i write it like this the function doesn't get called at all.

What's the problem here?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

丢了幸福的猪 2024-09-07 01:18:46

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

使用将 FocusPolicy 设置为 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();
}

EDIT:
As pointed out by other users, the method I outlined originally is not the proper way to resolve this.
Answer by Vasco Rinaldo

Use Set the FocusPolicy to Qt::ClickFocus to get the keybordfocus by
mouse klick. setFocusPolicy(Qt::ClickFocus);

The previous (albeit imperfect) solution I gave is given below:

Looks like your widget is not getting "focus". Override your mouse press event:

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

Here's the source code for a working example:

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();
}
老子叫无熙 2024-09-07 01:18:46

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

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

setFocusPolicy(Qt::ClickFocus);

正如手册中所说:

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

如果小部件通过 Tab 键接受键盘焦点,则策略为 Qt::TabFocus;如果小部件通过单击接受焦点,则策略为 Qt::ClickFocus;如果接受两者,则策略为 Qt::StrongFocus;如果它根本不接受焦点。

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

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

You don't have to reimplement mousePressEvent yourself just to call setFocus. Qt planed it already.

Set the FocusPolicy to Qt::ClickFocus to get the keybordfocus by mouse klick.

setFocusPolicy(Qt::ClickFocus);

As said in the manual:

This property holds the way the widget accepts keyboard focus.

The policy is Qt::TabFocus if the widget accepts keyboard focus by tabbing, Qt::ClickFocus if the widget accepts focus by clicking, Qt::StrongFocus if it accepts both, and Qt::NoFocus (the default) if it does not accept focus at all.

You must enable keyboard focus for a widget if it processes keyboard events. This is normally done from the widget's constructor. For instance, the QLineEdit constructor calls setFocusPolicy(Qt::StrongFocus).

If the widget has a focus proxy, then the focus policy will be propagated to it.

流云如水 2024-09-07 01:18:46

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

Set the FocusPolicy to Qt::ClickFocus to get the keybordfocus by mouse klick.
setFocusPolicy(Qt::ClickFocus);

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文