问题
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();
}
回答1:
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:
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.
回答2:
QGraphicsView reimplements keyPressEvent and will forward events to the QGraphicsScene. QGraphicsScene supports key presses through its keyPressEvent handler. By default the QGraphicsScene will forward that key press to the current QGraphicsItem through its keyPressEvent function.
Given the above, what you likely want to do is reimplement the keyPressEvent
handler in your 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.
Besides implementing QObject::installEventFilter, you could also subclass any of QGraphicsView, QGraphicsScene, or QGraphicsItem and override the keyPressEvent function.
回答3:
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!
回答4:
Your choice of QGraphicsView
isn't very fortunate.
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.
来源:https://stackoverflow.com/questions/6083829/qt-catch-pressed-key