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

QGraphicsItem to react on CTRL left click

Scheduled Pinned Locked Moved General and Desktop
18 Posts 5 Posters 4.7k 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