简体   繁体   中英

Qt catch pressed key

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

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.

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.

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!

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM