C++ Qt 捕捉按下的键
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6083829/
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
Qt catch pressed key
提问by Tebe
i think of to write primitive snake. i have window where program paints random lines.
我想到写原始蛇。我有程序在其中绘制随机线的窗口。
but i can't think up how to catch pressed key to change direction of painted line.
但我想不出如何抓住按键来改变画线的方向。
class QUpdatingPathIte : public QGraphicsPathItem
{
void advance(int phase)
{
if (phase == 0)
return;
int x,y;
int w,a,s,d;
char c;
//
// HOW TO MAKE THIS HERE? (i had done early in console application)
// but i can't do this in GUI , what should i do?
scanf("%c",&c);
if (c=='w')
{ x=-20; y=0; }
else if (c=='s')
{ x=20; y=0; }
else if (c=='a')
{ x=0; y=-20; }
else if(c=='d')
{ x=0; y=20; }
QPainterPath p = path();
p.lineTo(x, y);
setPath(p);
}
};
#include <QtGui/QApplication>
#include "dialog.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QGraphicsScene s;
QGraphicsView v(&s);
QUpdatingPathIte item;
item.setPen(QPen(QColor("black")));
s.addItem(&item);
v.show();
QTimer *timer = new QTimer(&s);
timer->connect(timer, SIGNAL(timeout()), &s, SLOT(advance()));
timer->start(500);
return a.exec();
}
回答by cdyer
QGraphicsView inherits from from QWidget because it inherits from QAbstractScrollArea. You should create a custom subclass of QGraphicsView and just override the function keyPressEvent(). Example:
QGraphicsView 继承自 QWidget,因为它继承自 QAbstractScrollArea。您应该创建 QGraphicsView 的自定义子类,并覆盖函数 keyPressEvent()。例子:
class SnakeView : public QGraphicsView
{
protected:
keyPressEvent(QKeyEvent *e)
{
// Do something
// Otherwise pass to the graphics view
QGraphicsView::keyPressEvent(e)
}
};
Then rather than creating a QGraphicsView object you would create a SnakeView object.
然后,您将创建一个 SnakeView 对象,而不是创建 QGraphicsView 对象。
回答by Kaleb Pederson
QGraphicsView reimplements keyPressEventand will forward events to the QGraphicsScene. QGraphicsScene supports key presses through its keyPressEventhandler. By default the QGraphicsScene will forward that key press to the current QGraphicsItem through its keyPressEventfunction.
QGraphicsView 重新实现了keyPressEvent并将事件转发到 QGraphicsScene。QGraphicsScene 通过其keyPressEvent处理程序支持按键操作。默认情况下,QGraphicsScene 将通过其keyPressEvent函数将该按键转发到当前 QGraphicsItem 。
Given the above, what you likely want to do is reimplement the keyPressEvent
handler in your QUpdatingPathItem
:
鉴于上述情况,您可能想要做的是keyPressEvent
在您的 中重新实现处理程序QUpdatingPathItem
:
void QUpdatingPathItem::keyPressEvent(QKeyEvent *event)
{
switch (event->key()) {
case Key::Key_A: /* do something useful */; break;
case Key::Key_S: /* do something useful */; break;
case Key::Key_W: /* do something useful */; break;
case Key::Key_D: /* do something useful */; break;
}
}
I couldn't really follow what you were trying to do in your advance
method, so I can't offer much in the way of a suggested handler.
我无法真正遵循您在advance
方法中尝试执行的操作,因此我无法提供建议处理程序的太多内容。
Besides implementing QObject::installEventFilter, you could also subclass any of QGraphicsView, QGraphicsScene, or QGraphicsItem and override the keyPressEvent function.
除了实现QObject::installEventFilter 之外,您还可以继承QGraphicsView、QGraphicsScene 或 QGraphicsItem 中的任何一个并覆盖 keyPressEvent 函数。
回答by Tebe
thanks you all. Then I didn't reach my aim. But time went on and I've come to the same problem and now I solved it.
谢谢大家。然后我没有达到我的目的。但是随着时间的流逝,我遇到了同样的问题,现在我解决了。
There are right and worth answers but then I wasn't good enough to put them together because no one was full and sufficient. Now I did it so:
有正确且有价值的答案,但后来我还不够好,无法将它们放在一起,因为没有人是完整的和足够的。现在我这样做了:
HEADER FILE "header.h"
class MyGraphicView: public QGraphicsView
{
Updating *m_update;
public:
MyGraphicView(Updating *update);
void keyPressEvent(QKeyEvent *event);
};
#include "header.h"
void GraphicView::keyPressEvent(QKeyEvent *event)
{
switch ( event->key())
{case Qt::Key_Up:
m_update->move_up();
break;
case Qt::Key_Down:
m_update->move_down();
break;
case Qt::Key_Left:
{ m_update->move_right();
break;
}
case Qt::Key_Right:
{ m_update->move_left();
break;
}
}
}
}
}
Thanks again!
再次感谢!
回答by ?imon Tóth
Your choice of QGraphicsView
isn't very fortunate.
你的选择QGraphicsView
不是很幸运。
Basically, when you are implementing some custom painted graphical item (the graphic area of the game is this), you should create your own widget and simply implement the QWidget::keyPressEvent()
method.
基本上,当您实现一些自定义绘制的图形项目(游戏的图形区域就是这个)时,您应该创建自己的小部件并简单地实现该QWidget::keyPressEvent()
方法。