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. QGraphicsObject: ContextMenu does not show up
Forum Updated to NodeBB v4.3 + New Features

QGraphicsObject: ContextMenu does not show up

Scheduled Pinned Locked Moved Solved General and Desktop
16 Posts 4 Posters 1.3k Views 1 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.
  • S sandro4912

    I added exec and now it shows up. I could swear i saw an example with only popup. However now that it shows up it is only is triggered when I right click in the first 1/4 of the widget.(like if the widget has half the height and width.

    I define boundingRect like this:

    QRectF Room::boundingRect() const
    {
        return QRectF{ QPointF{0, 0}, roomImage().size()};
    }
    

    were roomImage is a ressource:

    QImage Room::roomImage() const
    {
        return QImage{":/ressources/room.png"};
    }
    

    to paint i do this:

    void Room::paint(
            QPainter *painter,
            const QStyleOptionGraphicsItem *option,
            QWidget *widget)
    {
        Q_UNUSED(option)
        Q_UNUSED(widget)
    
        drawRoom(painter);
    }
    
    void Room::drawRoom(QPainter *painter)
    {
        painter->drawImage(boundingRect(), roomImage());
    }
    
    JonBJ Online
    JonBJ Online
    JonB
    wrote on last edited by
    #4

    @sandro4912
    popup() can be used, but not with a stack variable QMenu like you had. Usually you'd new it.

    For the area now: does ":/ressources/room.png" match how you spell resources on disk? Or you need to look at roomImage().size().

    1 Reply Last reply
    1
    • S Offline
      S Offline
      sandro4912
      wrote on last edited by
      #5

      if i create menu dynamically who deallocates it later? I can't assign the Room to it as a parent since is not derrived from QWidget.

      Also i tryed:

      void Room::drawRoom(QPainter *painter)
      {
          qDebug() << boundingRect();
          qDebug() << roomImage().size();
      
          painter->drawImage(boundingRect(), roomImage());
      }
      

      Which outputs:

      QRectF(0,0 100x100)
      QSize(100, 100)
      

      So it should theoretically pop the menu in the whole image but it doesn't?

      JonBJ 1 Reply Last reply
      0
      • SGaistS Offline
        SGaistS Offline
        SGaist
        Lifetime Qt Champion
        wrote on last edited by
        #6

        Hi,

        Make it a member variable and delete it in your class destructor.

        Interested in AI ? www.idiap.ch
        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

        1 Reply Last reply
        2
        • S sandro4912

          if i create menu dynamically who deallocates it later? I can't assign the Room to it as a parent since is not derrived from QWidget.

          Also i tryed:

          void Room::drawRoom(QPainter *painter)
          {
              qDebug() << boundingRect();
              qDebug() << roomImage().size();
          
              painter->drawImage(boundingRect(), roomImage());
          }
          

          Which outputs:

          QRectF(0,0 100x100)
          QSize(100, 100)
          

          So it should theoretically pop the menu in the whole image but it doesn't?

          JonBJ Online
          JonBJ Online
          JonB
          wrote on last edited by JonB
          #7

          @sandro4912
          For dynamically created QMenu, then as @SGaist says.

          But are you sure you need QMenu:popUp() and not just QMenu::exec() for your use case? It depends how you want it to work. If the simple exec() suffices you should be able to just use a stack (local) variable QMenu menu. You don't need the menu after it has returned the action the user clicked.

          For your coordinates/click area, I don't think we're going to know. Is your image indeed 100x100 size, or is that maybe some default? Why don't you play with a bigger/smaller image and see what the pattern is?

          1 Reply Last reply
          1
          • S Offline
            S Offline
            sandro4912
            wrote on last edited by sandro4912
            #8

            there is nothing wrong with the image but to sort it out i did this:

            void Room::paint(
                    QPainter *painter,
                    const QStyleOptionGraphicsItem *option,
                    QWidget *widget)
            {
                QRectF rect{boundingRect()};
                painter->setPen(Qt::black);
                painter->drawRect(rect);
            }
            
            QRectF Room::boundingRect() const
            {
                return QRectF{ 0, 0, 200, 200};
            }
            

            Still the Menu is not popped up on the whole rect. It only appeas like on 1/3 of the size of QRectF{ 0, 0, 200, 200}; so is not always half. Does contextMenuEvent maybe check the size from somewhere else but not from the boundingRect ? Or is this simply a bug in QT?

            I also compiled the code an a second OS to sort out that its not annother bug with KDE/Neon. But on Windows 10 same behaviour.

            Also I stayed with the local Menu:

            void Room::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
            {
                qDebug() << boundingRect();
                qDebug() << roomImage().size();
            
                QMenu menu;
                menu.addAction(mGuessWumpusAction);
                menu.addAction(mGuessBatAction);
                menu.addAction(mGuessPitAction);
                menu.exec(event->screenPos());
            }
            

            Any more ideas??

            Christian EhrlicherC 1 Reply Last reply
            0
            • S Offline
              S Offline
              sandro4912
              wrote on last edited by
              #9

              let me know if you need more information to find a solution for this issue. Maybe is even a qt bug.

              1 Reply Last reply
              0
              • S sandro4912

                there is nothing wrong with the image but to sort it out i did this:

                void Room::paint(
                        QPainter *painter,
                        const QStyleOptionGraphicsItem *option,
                        QWidget *widget)
                {
                    QRectF rect{boundingRect()};
                    painter->setPen(Qt::black);
                    painter->drawRect(rect);
                }
                
                QRectF Room::boundingRect() const
                {
                    return QRectF{ 0, 0, 200, 200};
                }
                

                Still the Menu is not popped up on the whole rect. It only appeas like on 1/3 of the size of QRectF{ 0, 0, 200, 200}; so is not always half. Does contextMenuEvent maybe check the size from somewhere else but not from the boundingRect ? Or is this simply a bug in QT?

                I also compiled the code an a second OS to sort out that its not annother bug with KDE/Neon. But on Windows 10 same behaviour.

                Also I stayed with the local Menu:

                void Room::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
                {
                    qDebug() << boundingRect();
                    qDebug() << roomImage().size();
                
                    QMenu menu;
                    menu.addAction(mGuessWumpusAction);
                    menu.addAction(mGuessBatAction);
                    menu.addAction(mGuessPitAction);
                    menu.exec(event->screenPos());
                }
                

                Any more ideas??

                Christian EhrlicherC Offline
                Christian EhrlicherC Offline
                Christian Ehrlicher
                Lifetime Qt Champion
                wrote on last edited by
                #10

                @sandro4912 said in QGraphicsObject: ContextMenu does not show up:

                Still the Menu is not popped up on the whole rect. It only appeas like on 1/3 of the size of QRectF{ 0, 0, 200, 200}; so is not always half. Does contextMenuEvent maybe check the size from somewhere else but not from the boundingRect ?

                I don't understand what you say here - does the popup / context menu event only works on 1/3 of your widget? Is the popup not as big as you expect?

                Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                Visit the Qt Academy at https://academy.qt.io/catalog

                1 Reply Last reply
                0
                • S Offline
                  S Offline
                  sandro4912
                  wrote on last edited by
                  #11

                  the popup itself looks perfect.

                  The problem is it does not get triggered in the whole 200x200 area of the widget. It only looks like it gets shown in a smaller rectangle from the top left point.

                  so in 200x200 maybe only in 80x80 from top left point it gets created.

                  I would expect in the whole rectangle the context menu gets triggere.

                  maybe i should make a minimal running example so it can be verifyed.

                  1 Reply Last reply
                  0
                  • Christian EhrlicherC Offline
                    Christian EhrlicherC Offline
                    Christian Ehrlicher
                    Lifetime Qt Champion
                    wrote on last edited by
                    #12

                    Ok, now it's clear to me. There are two examples (diagramscene, boxes) which work fine for me. Maybe you can try them out.

                    Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                    Visit the Qt Academy at https://academy.qt.io/catalog

                    1 Reply Last reply
                    0
                    • S Offline
                      S Offline
                      sandro4912
                      wrote on last edited by
                      #13

                      I made a minimal program and it works:

                      #ifndef RECTANGLE_H
                      #define RECTANGLE_H
                      
                      #include <QGraphicsObject>
                      
                      class Rectangle : public QGraphicsObject
                      {
                          Q_OBJECT
                      public:
                          explicit Rectangle(QGraphicsObject *parent = nullptr);
                      
                          QRectF boundingRect() const override;
                      
                          void paint(QPainter *painter,
                                     const QStyleOptionGraphicsItem *option,
                                     QWidget *widget) override;
                      
                      protected:
                          void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) override;
                      };
                      
                      #endif // RECTANGLE_H
                      
                      #include "rectangle.h"
                      
                      #include <QGraphicsSceneContextMenuEvent>
                      #include <QPainter>
                      #include <QMenu>
                      
                      Rectangle::Rectangle(QGraphicsObject *parent)
                          : QGraphicsObject(parent)
                      {
                      }
                      
                      QRectF Rectangle::boundingRect() const
                      {
                          return QRectF{ 0, 0, 100, 100};
                      }
                      
                      void Rectangle::paint(
                              QPainter *painter,
                              const QStyleOptionGraphicsItem *option,
                              QWidget *widget)
                      {
                          Q_UNUSED(option)
                          Q_UNUSED(widget)
                      
                          QRectF rect{boundingRect()};
                          painter->setPen(Qt::black);
                          painter->drawRect(rect);
                      }
                      
                      void Rectangle::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
                      {
                          QMenu menu;
                          menu.addAction("Action 1");
                          menu.addAction("Action 2");
                          menu.exec(event->screenPos());
                      }
                      
                      #include "rectangle.h"
                      
                      #include <QApplication>
                      #include <QGraphicsScene>
                      #include <QGraphicsView>
                      
                      int main(int argc, char *argv[])
                      {
                          QApplication app(argc, argv);
                      
                          QGraphicsScene scene;
                      
                          Rectangle rectangle;
                          scene.addItem(&rectangle);
                      
                          QGraphicsView view;
                          view.setScene(&scene);
                      
                          view.show();
                          return QApplication::exec();
                      }
                      

                      Everything fine here the popup shows up in all the widget. The reason it does not work in my programm is. At some point i changed the class from QGraphicsObject to QGraphicsWidget. If we modify the minimal programm to have QGraphicsWidget as a base for Rectangle we get the Issue again:

                      #ifndef RECTANGLE_H
                      #define RECTANGLE_H
                      
                      #include <QGraphicsWidget>
                      
                      class Rectangle : public QGraphicsWidget
                      {
                          Q_OBJECT
                      public:
                          explicit Rectangle(QGraphicsWidget *parent = nullptr);
                      
                          QRectF boundingRect() const override;
                      
                          void paint(QPainter *painter,
                                     const QStyleOptionGraphicsItem *option,
                                     QWidget *widget) override;
                      
                      protected:
                          void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) override;
                      };
                      
                      #endif // RECTANGLE_H
                      
                      #include "rectangle.h"
                      
                      #include <QGraphicsSceneContextMenuEvent>
                      #include <QPainter>
                      #include <QMenu>
                      
                      Rectangle::Rectangle(QGraphicsWidget *parent)
                          : QGraphicsWidget(parent)
                      {
                      }
                      
                      QRectF Rectangle::boundingRect() const
                      {
                          return QRectF{ 0, 0, 100, 100};
                      }
                      
                      void Rectangle::paint(
                              QPainter *painter,
                              const QStyleOptionGraphicsItem *option,
                              QWidget *widget)
                      {
                          Q_UNUSED(option)
                          Q_UNUSED(widget)
                      
                          QRectF rect{boundingRect()};
                          painter->setPen(Qt::black);
                          painter->drawRect(rect);
                      }
                      
                      void Rectangle::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
                      {
                          QMenu menu;
                          menu.addAction("Action 1");
                          menu.addAction("Action 2");
                          menu.exec(event->screenPos());
                      }
                      
                      #include "rectangle.h"
                      
                      #include <QApplication>
                      #include <QGraphicsScene>
                      #include <QGraphicsView>
                      
                      int main(int argc, char *argv[])
                      {
                          QApplication app(argc, argv);
                      
                          QGraphicsScene scene;
                      
                          Rectangle rectangle;
                          scene.addItem(&rectangle);
                      
                          QGraphicsView view;
                          view.setScene(&scene);
                      
                          view.show();
                          return QApplication::exec();
                      }
                      

                      So why is the behaviour different with QGraphicWidget? How can it get fixed there?

                      1 Reply Last reply
                      0
                      • Christian EhrlicherC Offline
                        Christian EhrlicherC Offline
                        Christian Ehrlicher
                        Lifetime Qt Champion
                        wrote on last edited by Christian Ehrlicher
                        #14

                        You forgot to set a proper size of the QGraphicsWidget: https://doc.qt.io/qt-5/qgraphicswidget.html#size-prop - since it's a widget you have to treat it like a widget which also means you have to set a proper size since there is no layout from where the size could be calculated from.

                        Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                        Visit the Qt Academy at https://academy.qt.io/catalog

                        1 Reply Last reply
                        2
                        • S Offline
                          S Offline
                          sandro4912
                          wrote on last edited by
                          #15

                          I solved the issue by resize in the constructor:

                              resize(boundingRect().size());
                          

                          That should be it or any other things to concern?

                          1 Reply Last reply
                          0
                          • Christian EhrlicherC Offline
                            Christian EhrlicherC Offline
                            Christian Ehrlicher
                            Lifetime Qt Champion
                            wrote on last edited by
                            #16

                            @sandro4912 said in QGraphicsObject: ContextMenu does not show up:

                            That should be it or any other things to concern?

                            That's fine.

                            Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                            Visit the Qt Academy at https://academy.qt.io/catalog

                            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