Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Capturing key press in QGraphicsView within main() function?

Capturing key press in QGraphicsView within main() function?

Scheduled Pinned Locked Moved Solved General and Desktop
qgraphicsviewqgraphicssceneclassmainkeypressevent
4 Posts 2 Posters 6.5k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • O Offline
    O Offline
    oblivioncth
    wrote on 10 Dec 2016, 03:11 last edited by oblivioncth 12 Oct 2016, 05:40
    #1

    Hello,

    I am trying to program a simple game that primarily uses QGraphicsScene and QGraphicsView, both of which are created in the main function of the program (I have no MainWindow). To have the user control the game I simply want them to use the arrow keys. So, I implemented a simple test function to make sure the methodology I researched works:

    void keyPressEvent( QKeyEvent* pe )
    {
        switch( pe->key() )
        {
            case Qt::Key_Space:
            {
            qDebug() << "Space pressed";
            }
            break;
         }
    }
    

    Unfortunately the function is never called. Looking into it some more it seems to me that "keyPressEvent" is a virtual function for widgets that you implement yourself to control its logic. I've seen a good number of examples that discuss this but all are in regards to MainWindow. It seems like I might need to implement a setFocus policy or install an event filter, but I'm not sure how to go about that for my QGraphicsScene since this is not happening within a class (all of the examples I've seen are for capturing key presses within MainWindow.

    If any more code is needed please let me know.

    Thanks again for this great forum.

    EDIT:

    Ok so I read a post on stack overflow that suggested making a custom class that inherits QGraphicsView and then override the keyPressEvent function there. But now I've run into trouble doing that.

    gameview.h:

    #ifndef GAMEVIEW_H
    #define GAMEVIEW_H
    
    #include <QtWidgets>
    
    class GameView : public QGraphicsView
    {
    public:
        GameView();
        void keyPressEvent(QKeyEvent *e);
    };
    
    #endif
    

    gameview.cpp:

    #include "gameview.h"
    
    GameView::GameView()
    {
    
    }
    
    void GameView::keyPressEvent(QKeyEvent *pe)
    {
        switch( pe->key() )
            {
                case Qt::Key_Space:
                {
                qDebug() << "Space pressed";
                }
                break;
             }
    }
    

    So now instead of a QGraphicsView I need to create a "GameView", but when I try to instantiate it and hook it to the QGraphicsScene I use:

    QGraphicsScene scene;
    scene.setSceneRect(0, 0, 800, 800);
    scene.setItemIndexMethod(QGraphicsScene::NoIndex);
    
    GameView view(&scene);
    

    I get this error:

    main.cpp:51: error: C2664: 'GameView::GameView(const GameView &)': cannot convert argument 1 from 'QGraphicsScene *' to 'const GameView &'
    

    Clearly something is wrong with binding the Gameview to the GraphicsScene but I'm not sure what. I don't know why its expecting a const GameView reference as a normal GraphicsView has either:

    QGraphicsView(QWidget * parent = 0)
    

    or

    QGraphicsView(QGraphicsScene * scene, QWidget * parent = 0)
    

    as its constructor and just wants a parent, but its probably a flaw in my implementation. I've never had to implement a class that inherits from another in C++/Qt so I'm not totally sure what the right way is.

    It would probably be easier for someone to help with this more specific issue but if you have a better idea for my original question feel free to post anyway.

    1 Reply Last reply
    0
    • ? Offline
      ? Offline
      A Former User
      wrote on 10 Dec 2016, 06:14 last edited by
      #2

      Hi! This is an answer to your original question. You can install an event filter on the QApplication object:

      keypresseventfilter.h

      #ifndef KEYPRESSEVENTFILTER_H
      #define KEYPRESSEVENTFILTER_H
      
      #include <QObject>
      
      class KeyPressEventFilter : public QObject
      {
          Q_OBJECT
      public:
          explicit KeyPressEventFilter(QObject *parent = nullptr);
      
      protected:
          bool eventFilter(QObject *obj, QEvent *event) override;
      };
      
      #endif // KEYPRESSEVENTFILTER_H
      

      keypresseventfilter.cpp

      #include "keypresseventfilter.h"
      
      #include <QKeyEvent>
      #include <QDebug>
      
      KeyPressEventFilter::KeyPressEventFilter(QObject *parent)
          : QObject(parent)
      {
      }
      
      bool KeyPressEventFilter::eventFilter(QObject *obj, QEvent *event)
      {
          if (event->type() != QEvent::KeyPress)
              return QObject::eventFilter(obj, event);
      
          QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
          switch(keyEvent->key()) {
          case Qt::Key_Space: { qDebug() << "Space"; break; }
          case Qt::Key_Left: { qDebug() << "Left"; break; }
          case Qt::Key_Right: { qDebug() << "Right"; break; }
          default: { qDebug() << "Unhandled"; break; }
          }
          return true;
      }
      

      main.cpp

      #include "mainwindow.h"
      #include <QApplication>
      
      #include "keypresseventfilter.h"
      
      int main(int argc, char *argv[])
      {
          QApplication a(argc, argv);
      
          KeyPressEventFilter *filter = new KeyPressEventFilter(&a);
          a.installEventFilter(filter);
      
          MainWindow w;
          w.show();
      
          return a.exec();
      }
      
      1 Reply Last reply
      3
      • ? Offline
        ? Offline
        A Former User
        wrote on 10 Dec 2016, 06:42 last edited by
        #3

        This is an answer to your modified question.

        customgraphicsview.h

        #ifndef CUSTOMGRAPHICSVIEW_H
        #define CUSTOMGRAPHICSVIEW_H
        
        #include <QGraphicsView>
        #include <QGraphicsScale>
        
        class CustomGraphicsView : public QGraphicsView
        {
            Q_OBJECT
        public:
            explicit CustomGraphicsView(QWidget *parent = nullptr);
            CustomGraphicsView(QGraphicsScene *scene, QWidget *parent = nullptr);
        protected:
            void keyPressEvent(QKeyEvent *event) override;
        };
        
        #endif // CUSTOMGRAPHICSVIEW_H
        

        customgraphicsview.cpp

        #include "customgraphicsview.h"
        
        #include <QKeyEvent>
        
        CustomGraphicsView::CustomGraphicsView(QWidget *parent)
            : QGraphicsView(parent)
        {
        }
        
        CustomGraphicsView::CustomGraphicsView(QGraphicsScene *scene, QWidget *parent)
            : QGraphicsView(scene, parent)
        {
        }
        
        void CustomGraphicsView::keyPressEvent(QKeyEvent *event)
        {
            switch(event->key()) {
            case Qt::Key_Space: { qDebug() << "Space"; break; }
            case Qt::Key_Left: { qDebug() << "Left"; break; }
            case Qt::Key_Right: { qDebug() << "Right"; break; }
            default: { qDebug() << "Unhandled"; break; }
            }
        }
        

        main.cpp

        #include <QApplication>
        
        #include "customgraphicsview.h"
        #include <QGraphicsScene>
        
        int main(int argc, char *argv[])
        {
            QApplication a(argc, argv);
        
            QGraphicsScene scene;
            CustomGraphicsView view(&scene);
            view.show();
        
            return a.exec();
        }
        
        O 1 Reply Last reply 10 Dec 2016, 06:51
        3
        • ? A Former User
          10 Dec 2016, 06:42

          This is an answer to your modified question.

          customgraphicsview.h

          #ifndef CUSTOMGRAPHICSVIEW_H
          #define CUSTOMGRAPHICSVIEW_H
          
          #include <QGraphicsView>
          #include <QGraphicsScale>
          
          class CustomGraphicsView : public QGraphicsView
          {
              Q_OBJECT
          public:
              explicit CustomGraphicsView(QWidget *parent = nullptr);
              CustomGraphicsView(QGraphicsScene *scene, QWidget *parent = nullptr);
          protected:
              void keyPressEvent(QKeyEvent *event) override;
          };
          
          #endif // CUSTOMGRAPHICSVIEW_H
          

          customgraphicsview.cpp

          #include "customgraphicsview.h"
          
          #include <QKeyEvent>
          
          CustomGraphicsView::CustomGraphicsView(QWidget *parent)
              : QGraphicsView(parent)
          {
          }
          
          CustomGraphicsView::CustomGraphicsView(QGraphicsScene *scene, QWidget *parent)
              : QGraphicsView(scene, parent)
          {
          }
          
          void CustomGraphicsView::keyPressEvent(QKeyEvent *event)
          {
              switch(event->key()) {
              case Qt::Key_Space: { qDebug() << "Space"; break; }
              case Qt::Key_Left: { qDebug() << "Left"; break; }
              case Qt::Key_Right: { qDebug() << "Right"; break; }
              default: { qDebug() << "Unhandled"; break; }
              }
          }
          

          main.cpp

          #include <QApplication>
          
          #include "customgraphicsview.h"
          #include <QGraphicsScene>
          
          int main(int argc, char *argv[])
          {
              QApplication a(argc, argv);
          
              QGraphicsScene scene;
              CustomGraphicsView view(&scene);
              view.show();
          
              return a.exec();
          }
          
          O Offline
          O Offline
          oblivioncth
          wrote on 10 Dec 2016, 06:51 last edited by oblivioncth 12 Oct 2016, 09:09
          #4

          @Wieland Wow you are just killing it today for me aren't you? Haha. I'll judge which is best for me a give it a roll.

          Thanks a bunch (again)!

          EDIT:

          I ended up going for the event filter route and it works beautifully. Other than the exact syntax the approach also feels pretty intuitive which I like.

          1 Reply Last reply
          0

          4/4

          10 Dec 2016, 06:51

          • Login

          • Login or register to search.
          4 out of 4
          • First post
            4/4
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • Users
          • Groups
          • Search
          • Get Qt Extensions
          • Unsolved