Qt catch pressed key

此生再无相见时 提交于 2019-12-10 10:43:26

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!