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?
Forum Updated to NodeBB v4.3 + New Features

Capturing key press in QGraphicsView within main() function?

Scheduled Pinned Locked Moved Solved General and Desktop
qgraphicsviewqgraphicssceneclassmainkeypressevent
4 Posts 2 Posters 6.6k Views 2 Watching
  • 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.
  • oblivioncthO Offline
    oblivioncthO Offline
    oblivioncth
    wrote on last edited by oblivioncth
    #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 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 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();
        }
        
        oblivioncthO 1 Reply Last reply
        3
        • ? A Former User

          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();
          }
          
          oblivioncthO Offline
          oblivioncthO Offline
          oblivioncth
          wrote on last edited by oblivioncth
          #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

          • Login

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