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. QGraphicsItem to react on CTRL left click

QGraphicsItem to react on CTRL left click

Scheduled Pinned Locked Moved General and Desktop
18 Posts 5 Posters 5.1k Views 4 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.
  • J Offline
    J Offline
    JanLaloux
    wrote on last edited by
    #3

    I tried the approach but it seems not working. I made a simple example with a class Circle that inherts from QGraphicsEllipseItem. Clicking on a circle does not trigger the Circle::mousePressEvent(). What am I missing?

    #include <QApplication>
    #include <QMessageBox>
    #include <QtWidgets/QMainWindow>
    #include <QtWidgets/QGraphicsScene>
    #include <QtWidgets/QGraphicsView>
    #include <QtWidgets/QGridLayout>
    #include <QtWidgets/QGraphicsEllipseItem>
    
    class Circle : public QGraphicsEllipseItem {
    public:
    	Circle::Circle(const qreal ax, const qreal ay, const qreal wx, const qreal wy, QGraphicsScene *scene) :
    		QGraphicsEllipseItem(ax, ay, wx, wy)
    	{
    		setPen( QPen(QBrush(Qt::black), 2, Qt::SolidLine, Qt::SquareCap, Qt::MiterJoin) );
    		setBrush( QBrush(Qt::gray) );
    		setRect(ax, ay, wx, wy);
    		setAcceptedMouseButtons(Qt::LeftButton | Qt::RightButton);
    		scene->addItem(this);
    	}
    
    	~Circle(){}
    
    	void Circle::mousePressEvent(QMouseEvent *event) {
    		QMessageBox msgBox;
    		QString QResult{ QString::fromLatin1("Circle clicked") };
    		msgBox.setText( QResult );
    		msgBox.exec();
    	}
    };
    
    
    
    class MainWindow : public QMainWindow
    {
    public:
    	QWidget *baseWidget;
    	QGridLayout *baseWidgetGrid;
    	QGraphicsScene *graphicsScene;
    	QGraphicsView *graphicsView;
    
    public:
    	MainWindow::MainWindow(QWidget *parent=0) :
    		QMainWindow(parent)
    	{
    		graphicsScene = new QGraphicsScene(0, 0, 100, 100);
    		new Circle(  5,  5, 20, 20, graphicsScene );
    		new Circle( 35, 35, 20, 20, graphicsScene );
    		new Circle( 65, 65, 20, 20, graphicsScene );
    
    		baseWidget = new QWidget(this);
    		baseWidgetGrid = new QGridLayout(baseWidget);
    			graphicsView = new QGraphicsView(baseWidget);
    			graphicsView->setScene(graphicsScene);
    		baseWidgetGrid->addWidget(graphicsView, 0, 0, 1, 1);
    
    		setCentralWidget(baseWidget);
    	}
    
    	~MainWindow(){}
    };
    
    
    int main(int argc, char *argv[])
    {
    	QApplication Application(argc, argv);
    	MainWindow MainWin;
    	MainWin.show();
    	return Application.exec();
    }
    
    
    1 Reply Last reply
    0
    • mrjjM Offline
      mrjjM Offline
      mrjj
      Lifetime Qt Champion
      wrote on last edited by mrjj
      #4

      Hmmm, you have listed it under public:
      Try move it to
      protected:
      Also normally its virtual

      so try with

      protected: virtual void Circle::mousePressEvent(QMouseEvent *event) { .. }

      note:
      you can remove the Circle:: when the function is implemented in the .H file.

      JohanSoloJ 1 Reply Last reply
      0
      • mrjjM mrjj

        Hmmm, you have listed it under public:
        Try move it to
        protected:
        Also normally its virtual

        so try with

        protected: virtual void Circle::mousePressEvent(QMouseEvent *event) { .. }

        note:
        you can remove the Circle:: when the function is implemented in the .H file.

        JohanSoloJ Offline
        JohanSoloJ Offline
        JohanSolo
        wrote on last edited by JohanSolo
        #5

        @mrjj said:

        Also normally its virtual

        so try with

        protected: virtual void Circle::mousePressEvent(QMouseEvent *event) { .. }

        From a purely technical point of view, the virtual is not necessary when reimplementing a virtual method, the `virtualness' is inherited from the base class. I therefore don't think this should help.

        `They did not know it was impossible, so they did it.'
        -- Mark Twain

        1 Reply Last reply
        0
        • J Offline
          J Offline
          JanLaloux
          wrote on last edited by
          #6

          No help, not with protected: nor protected: virtual ...

          mrjjM 1 Reply Last reply
          0
          • J JanLaloux

            No help, not with protected: nor protected: virtual ...

            mrjjM Offline
            mrjjM Offline
            mrjj
            Lifetime Qt Champion
            wrote on last edited by
            #7

            @JanLaloux
            Ok, Im on mobile so cant check the code.
            Have a look at the 40000 sample (in chip.h)
            It has a clickable item.

            1 Reply Last reply
            0
            • J Offline
              J Offline
              JanLaloux
              wrote on last edited by
              #8

              I noticed in Chip that the event passed is of type QGraphicsSceneMouseEvent * instead of QMouseEvent *. Changed it and now it works, even as public. Thanks for the support!

              mrjjM 1 Reply Last reply
              0
              • J JanLaloux

                I noticed in Chip that the event passed is of type QGraphicsSceneMouseEvent * instead of QMouseEvent *. Changed it and now it works, even as public. Thanks for the support!

                mrjjM Offline
                mrjjM Offline
                mrjj
                Lifetime Qt Champion
                wrote on last edited by
                #9

                @JanLaloux
                Good spotted! :)

                1 Reply Last reply
                0
                • Chris KawaC Online
                  Chris KawaC Online
                  Chris Kawa
                  Lifetime Qt Champion
                  wrote on last edited by
                  #10

                  On a side note: when overriding virtual methods use the override specifier. This way you'll get an instant error message at compile time if you make a typo or mismatch arguments like in this case.

                  1 Reply Last reply
                  0
                  • J Offline
                    J Offline
                    JanLaloux
                    wrote on last edited by
                    #11

                    OK, now I understand the meaning of the Q_DECL_OVERRIDE macro I used to see in the examples...

                    1 Reply Last reply
                    0
                    • J Offline
                      J Offline
                      JanLaloux
                      wrote on last edited by
                      #12

                      I have modified my example. The mouse click works but I experience something strange. After something was clicked whatever click anywhere on the scene triggers the same mouse click method of the first clicked object! Any ideas on this?

                      #include <string>;
                      #include <QtWidgets/QApplication>
                      #include <QtWidgets/QMessageBox>
                      #include <QtWidgets/QMainWindow>
                      #include <QtWidgets/QGraphicsScene>
                      #include <QtWidgets/QGraphicsView>
                      #include <QtWidgets/QGridLayout>
                      #include <QtWidgets/QGraphicsEllipseItem>
                      
                      using namespace std;
                      
                      
                      class Circle : public QGraphicsEllipseItem {
                      public:
                      	Circle::Circle(int Id, const qreal ax, const qreal ay, const qreal wx, const qreal wy, QGraphicsScene *scene) :
                      		QGraphicsEllipseItem(ax, ay, wx, wy),
                      		Id(Id)
                      	{
                      		setPen( QPen(QBrush(Qt::black), 1, Qt::SolidLine, Qt::SquareCap, Qt::MiterJoin) );
                      		setBrush( QBrush(Qt::gray) );
                      		setRect(ax, ay, wx, wy);
                      		setAcceptedMouseButtons(Qt::LeftButton | Qt::RightButton);
                      		scene->addItem(this);
                      	}
                      
                      	~Circle(){}
                      
                      	void Circle::mousePressEvent(QGraphicsSceneMouseEvent *event) {
                      		QMessageBox msgBox;
                      		string msg{ "Circle " + to_string(Id) + " clicked" };
                      		QString QResult{ QString::fromLatin1(msg.c_str()) };
                      		msgBox.setText( QResult );
                      		msgBox.exec();
                      	}
                      	int Id;
                      };
                      
                      
                      
                      
                      class MainWindow : public QMainWindow
                      {
                      public:
                      	QWidget *baseWidget;
                      	QGridLayout *baseWidgetGrid;
                      	QGraphicsScene *graphicsScene;
                      	QGraphicsView *graphicsView;
                      
                      public:
                      	MainWindow::MainWindow(QWidget *parent=0) :
                      		QMainWindow(parent)
                      	{
                      		graphicsScene = new QGraphicsScene(0, 0, 120, 120);
                      		graphicsScene->addRect( 10, 10,  100, 100 );
                      		new Circle( 1, 20, 20, 20, 20, graphicsScene );
                      		new Circle( 2, 75, 75, 20, 20, graphicsScene );
                      
                      		baseWidget = new QWidget(this);
                      		baseWidgetGrid = new QGridLayout(baseWidget);
                      			graphicsView = new QGraphicsView(baseWidget);
                      			graphicsView->setRenderHint(QPainter::Antialiasing);
                      			graphicsView->setScene(graphicsScene);
                      		baseWidgetGrid->addWidget(graphicsView, 0, 0, 1, 1);
                      
                      		setCentralWidget(baseWidget);
                      	}
                      
                      	~MainWindow(){}
                      };
                      
                      
                      int main(int argc, char *argv[])
                      {
                      	QApplication Application(argc, argv);
                      	MainWindow MainWin;
                      	MainWin.show();
                      	return Application.exec();
                      }
                      
                      1 Reply Last reply
                      0
                      • mrjjM Offline
                        mrjjM Offline
                        mrjj
                        Lifetime Qt Champion
                        wrote on last edited by mrjj
                        #13

                        @JanLaloux said:

                        so when clicking outside, it would still say
                        "Circle " bla bla from the msgBox ?

                        I wonder if scene or view need
                        setMouseTracking(true);

                        J 1 Reply Last reply
                        0
                        • mrjjM mrjj

                          @JanLaloux said:

                          so when clicking outside, it would still say
                          "Circle " bla bla from the msgBox ?

                          I wonder if scene or view need
                          setMouseTracking(true);

                          J Offline
                          J Offline
                          JanLaloux
                          wrote on last edited by
                          #14

                          @mrjj
                          Yes, wherever you click on the scene you get the messagebox with the ID of the circle that was first clicked. The code I included is "ready to go" if you want to try it.

                          mrjjM 1 Reply Last reply
                          0
                          • J JanLaloux

                            @mrjj
                            Yes, wherever you click on the scene you get the messagebox with the ID of the circle that was first clicked. The code I included is "ready to go" if you want to try it.

                            mrjjM Offline
                            mrjjM Offline
                            mrjj
                            Lifetime Qt Champion
                            wrote on last edited by mrjj
                            #15

                            @JanLaloux
                            Hi , very strange. it said nothing when I clicked. not on circle or outside.

                            update:
                            Ahh I see that older post used QGraphicsSceneMouseEvent and not QMouseEvent
                            so just copy & paste error I guess.

                            I then added

                            protected:
                                virtual void mousePressEvent(QGraphicsSceneMouseEvent *event) {
                                qDebug() << "test";
                                }
                            

                            to Circle and now it print test when click on circle but not outside.

                            So not really sure whats going on.

                            Does that work for you too?

                            #include <QApplication>
                            #include <QMessageBox>
                            #include <QtWidgets/QMainWindow>
                            #include <QtWidgets/QGraphicsScene>
                            #include <QtWidgets/QGraphicsView>
                            #include <QtWidgets/QGridLayout>
                            #include <QtWidgets/QGraphicsEllipseItem>
                            #include <qDebug>
                            
                            class Circle : public QGraphicsEllipseItem {
                            public:
                                Circle(const qreal ax, const qreal ay, const qreal wx, const qreal wy, QGraphicsScene *scene) :
                                    QGraphicsEllipseItem(ax, ay, wx, wy)
                                {
                                    setPen( QPen(QBrush(Qt::black), 2, Qt::SolidLine, Qt::SquareCap, Qt::MiterJoin) );
                                    setBrush( QBrush(Qt::gray) );
                                    setRect(ax, ay, wx, wy);
                                    setAcceptedMouseButtons(Qt::LeftButton | Qt::RightButton);
                                    scene->addItem(this);
                                }
                            
                                ~Circle(){}
                            protected:
                                virtual void mousePressEvent(QGraphicsSceneMouseEvent *event) {
                                qDebug() << "test";
                                }
                            
                               virtual void mousePressEvent(QMouseEvent *event) {
                                    QMessageBox msgBox;
                                    QString QResult("DEER");
                                    msgBox.setText( QResult );
                                    msgBox.exec();
                                }
                            };
                            
                            
                            
                            class MainWindow : public QMainWindow
                            {
                            public:
                                QWidget *baseWidget;
                                QGridLayout *baseWidgetGrid;
                                QGraphicsScene *graphicsScene;
                                QGraphicsView *graphicsView;
                            
                            public:
                                MainWindow(QWidget *parent=0) :
                                    QMainWindow(parent)
                                {
                                    graphicsScene = new QGraphicsScene(0, 0, 100, 100);
                                    new Circle(  5,  5, 20, 20, graphicsScene );
                                    new Circle( 35, 35, 20, 20, graphicsScene );
                                    new Circle( 65, 65, 20, 20, graphicsScene );
                            
                                    baseWidget = new QWidget(this);
                                    baseWidgetGrid = new QGridLayout(baseWidget);
                                        graphicsView = new QGraphicsView(baseWidget);
                                        graphicsView->setScene(graphicsScene);
                                    baseWidgetGrid->addWidget(graphicsView, 0, 0, 1, 1);
                            
                                    setCentralWidget(baseWidget);
                                }
                            
                                ~MainWindow(){}
                            };
                            
                            
                            int main(int argc, char *argv[])
                            {
                                QApplication Application(argc, argv);
                                MainWindow MainWin;
                                MainWin.show();
                                return Application.exec();
                            }
                            
                            1 Reply Last reply
                            0
                            • J Offline
                              J Offline
                              JanLaloux
                              wrote on last edited by
                              #16

                              It's the msgBox that is the culprit!
                              Replace the qDebug output with the messagebox I used in my code and it goes wrong. The behaviour is as it should without it, I suppose this is a bug...
                              Remark: it is not needed to make the member protected
                              Anyway, thanks a lot for the help!

                              1 Reply Last reply
                              0
                              • mrjjM Offline
                                mrjjM Offline
                                mrjj
                                Lifetime Qt Champion
                                wrote on last edited by
                                #17

                                aha!
                                Pretty strange.

                                ok, its a habit for mousepressed for widgets :)

                                np. Good with code you can just run :)

                                1 Reply Last reply
                                0
                                • W Offline
                                  W Offline
                                  willems1994
                                  wrote on last edited by
                                  #18

                                  For people having the same problem that the QMessageBox keeps appearing anywhere you click, you can fix it by ungrabbing the mouse after closing the box:

                                  scene->mouseGrabberItem()->ungrabMouse();
                                  

                                  @JanLaloux said in QGraphicsItem to react on CTRL left click:

                                  @mrjj
                                  Yes, wherever you click on the scene you get the messagebox with the ID of the circle that was first clicked. The code I included is "ready to go" if you want to try it.

                                  1 Reply Last reply
                                  2

                                  • Login

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