C++ QWidget keyPressEvent 覆盖
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2733668/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
QWidget keyPressEvent override
提问by Erik Aigner
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.
我现在正在尝试覆盖 QT 中的 QWidgets keyPressEvent 函数,但它不起作用。我不得不说我是 CPP 的新手,但我知道 ObjC 和标准 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.
QSGameBoard 是我的 QWidget 子类,我需要覆盖 keyPressEvent 并在每个事件上触发 SIGNAL 以通知一些已注册的对象。
My overridden keyPressEvent in QSGameBoard.cpp looks like this:
我在 QSGameBoard.cpp 中重写的 keyPressEvent 如下所示:
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.
当我将 QSGameBoard:: 更改为 QWidget:: 时,它会接收事件,但我无法发出信号,因为编译器会抱怨范围。如果我这样写,该函数根本不会被调用。
What's the problem here?
这里有什么问题?
采纳答案by Gayan
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);
使用 Set the FocusPolicy to Qt::ClickFocus 以通过鼠标点击获取 keybordfocus。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
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
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();
}
回答by squid
You don't have to reimplement mousePressEventyourself just to call setFocus. Qt planed it already.
您不必为了调用setFocus 而自己重新实现mousePressEvent。Qt 已经计划好了。
Set the FocusPolicy
to Qt::ClickFocus
to get the keybordfocus by mouse klick.
设置FocusPolicy
以Qt::ClickFocus
获得通过鼠标克利克的keybordfocus。
setFocusPolicy(Qt::ClickFocus);
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.
此属性保存小部件接受键盘焦点的方式。
策略是 Qt::TabFocus 如果小部件通过 Tab 键接受键盘焦点,Qt::ClickFocus 如果小部件通过点击接受焦点,Qt::StrongFocus 如果它同时接受,Qt::NoFocus(默认)如果它不接受完全接受焦点。
如果小部件处理键盘事件,则必须为小部件启用键盘焦点。这通常是通过小部件的构造函数完成的。例如,QLineEdit 构造函数调用 setFocusPolicy(Qt::StrongFocus)。
如果小部件具有焦点代理,则焦点策略将传播到它。
回答by Vasco Rinaldo
Set the FocusPolicy to Qt::ClickFocus to get the keybordfocus by mouse klick. setFocusPolicy(Qt::ClickFocus);
将 FocusPolicy 设置为 Qt::ClickFocus 以通过鼠标点击获取 keybordfocus。setFocusPolicy(Qt::ClickFocus);