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. Why is the action from a context menu on a popup dialog not triggered?
QtWS25 Last Chance

Why is the action from a context menu on a popup dialog not triggered?

Scheduled Pinned Locked Moved Solved General and Desktop
qt5qmenuqdialogpopup
14 Posts 2 Posters 7.8k 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.
  • J Offline
    J Offline
    Jakob
    wrote on 21 Jun 2016, 14:31 last edited by
    #1

    We have a dialog that derives from QDialog with roughly the following implementation:

    MyDialog::MyDialog(QWidget* parent)
        : QDialog(parent, Qt::Popup)
    {
        ui.setupUi(this);
        ui.textMetadata->setContextMenuPolicy(Qt::CustomContextMenu);
        connect(ui.textMetadata, &QTextEdit::customContextMenuRequested,
           this, &MyDialog::ShowContextMenu);
    }
    void MyDialog::copyAsTextToClipboard(bool )
    {
        QApplication::clipboard()->setText(data); // where data comes from within our application
    }
    
    void MyDialog::ShowContextMenu(const QPoint &pt)
    {
        QMenu* menu = ui.textMetadata->createStandardContextMenu();
        QAction* copyAsText = menu->addAction("Copy as text");
        connect(copyAsText, &QAction::triggered, this, &MyDialog::CopyAsTextToClipboard);
        menu->exec(ui.textMetadata->mapToGlobal(pt));
    }
    

    This code worked fine when I didn't construct the dialog with Qt::Popup - however, when passing this flag MyDialog::CopyAsTextToClipboard never gets executed when clicking the Copy as text action. As a matter of fact, the default Select All action that is created by default in the context menu, is also not executed.

    Why?

    1 Reply Last reply
    0
    • S Offline
      S Offline
      SGaist
      Lifetime Qt Champion
      wrote on 21 Jun 2016, 21:54 last edited by
      #2

      Hi,

      Sounds like it could be a bug.

      You should check the bug report system to see if there's something about that.

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

      J 1 Reply Last reply 22 Jun 2016, 07:25
      0
      • S SGaist
        21 Jun 2016, 21:54

        Hi,

        Sounds like it could be a bug.

        You should check the bug report system to see if there's something about that.

        J Offline
        J Offline
        Jakob
        wrote on 22 Jun 2016, 07:25 last edited by
        #3

        @SGaist Hm, that would be quite unfortunate - I'll check.

        In the meantime, I realized that there is an additional piece of information that may be quite relevant to this, which is how the dialog is constructed. Most of the widgets in our application are always there, including dialogs - they are just not always shown. This particular case is constructed as a result of the right click on an underlying widget:

        void GenericHandler::GetPropertiesClicked(QWidget* widget)
        {
            MyDialog dialog(widget);
            dialog.LoadMetadata(widget->GetMetadata());
            dialog.exec();
        }
        

        The panel is used to display metadata (not the Qt-stuff, but metadata relevant to our application) that comes along with the image data that is displayed on right-clicking the display and selecting an 'Show properties' option in the context menu that is popped up.

        So the dialog is destructed as soon as 'exec()' returns. I was wondering if there is a possibility that this causes the signal to never arrive when the dialog is in popup mode.

        1 Reply Last reply
        0
        • S Offline
          S Offline
          SGaist
          Lifetime Qt Champion
          wrote on 22 Jun 2016, 22:46 last edited by
          #4

          Very important detail indeed. Your dialog is modal to the widget you pass as parent thus it will block all inputs on it. See the WindowModality enum.

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

          J 1 Reply Last reply 23 Jun 2016, 19:45
          0
          • S SGaist
            22 Jun 2016, 22:46

            Very important detail indeed. Your dialog is modal to the widget you pass as parent thus it will block all inputs on it. See the WindowModality enum.

            J Offline
            J Offline
            Jakob
            wrote on 23 Jun 2016, 19:45 last edited by
            #5

            @SGaist Thanx for answering - I thought I understand this, but the signal I expected to be arriving in the dialog, hence not the underlying (blocked) widget, and then be picked up by the handler, which is also implemented in the dialog itself. As far as I can tell all 'action' is happening, and restricted to the dialog itself, and not to the underlying, blocked widget.

            Or am I misunderstanding something here? The funny thing, when the same dialog is created and displayed like this without the Qt::Popup flag, these triggered signals do arrive.

            1 Reply Last reply
            0
            • S Offline
              S Offline
              SGaist
              Lifetime Qt Champion
              wrote on 23 Jun 2016, 22:13 last edited by
              #6

              My bad, I've mixed your widget setup with another one. You understood right.

              Do you experience the same if you make a dialog instance on the heap with the dialog->setAttribute(Qt::WA_DeleteOnClose); and call open on it rather than exec ?

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

              J 1 Reply Last reply 24 Jun 2016, 07:50
              0
              • S SGaist
                23 Jun 2016, 22:13

                My bad, I've mixed your widget setup with another one. You understood right.

                Do you experience the same if you make a dialog instance on the heap with the dialog->setAttribute(Qt::WA_DeleteOnClose); and call open on it rather than exec ?

                J Offline
                J Offline
                Jakob
                wrote on 24 Jun 2016, 07:50 last edited by Jakob
                #7

                @SGaist Unfortunately that doesn't improve things.

                In the meantime I attached a debugger, and put a breakpoint in the QAction::activate implementation, which seems to the function that should handle all triggered actions. I never hit this breakpoint when I click the 'Copy as text' menu item, nor when I click the default constructed 'Select all' menu item.

                It seems almost as if the connection is not made for some reason, or destroyed before it is handled.

                J 1 Reply Last reply 24 Jun 2016, 08:23
                0
                • J Jakob
                  24 Jun 2016, 07:50

                  @SGaist Unfortunately that doesn't improve things.

                  In the meantime I attached a debugger, and put a breakpoint in the QAction::activate implementation, which seems to the function that should handle all triggered actions. I never hit this breakpoint when I click the 'Copy as text' menu item, nor when I click the default constructed 'Select all' menu item.

                  It seems almost as if the connection is not made for some reason, or destroyed before it is handled.

                  J Offline
                  J Offline
                  Jakob
                  wrote on 24 Jun 2016, 08:23 last edited by Jakob
                  #8

                  @SGaist I did some more investigation inside the debugger.

                  • the QMenu::mouseReleaseEvent() method is called
                  • However, the d->currentAction is nullptr, and for that reason the handler never executes d->activeAction()

                  [EDIT] Diving further, it seems in QMenuPrivate::setSyncAction() the currentAction is not set, while it is set when not passing the Qt::Popup flag.

                  1 Reply Last reply
                  0
                  • S Offline
                    S Offline
                    SGaist
                    Lifetime Qt Champion
                    wrote on 29 Jun 2016, 22:47 last edited by
                    #9

                    On which OS are you currently ?

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

                    J 2 Replies Last reply 1 Jul 2016, 13:22
                    0
                    • S SGaist
                      29 Jun 2016, 22:47

                      On which OS are you currently ?

                      J Offline
                      J Offline
                      Jakob
                      wrote on 1 Jul 2016, 13:22 last edited by
                      #10

                      @SGaist The OS is windows 7, with qt 5.6.0.

                      1 Reply Last reply
                      0
                      • S SGaist
                        29 Jun 2016, 22:47

                        On which OS are you currently ?

                        J Offline
                        J Offline
                        Jakob
                        wrote on 18 Jul 2016, 11:40 last edited by
                        #11

                        @SGaist I managed to create a compilable example that reproduces the problem. Hopefully that helps.

                        When using the line commented with OKE the line that prints some text to qInfo() is executed - when using the other line, that function is never executed (because the action is never 'activated')

                        #include <QAction>
                        #include <QApplication>
                        #include <QFrame>
                        #include <QMenu>
                        #include <QtDebug>
                        #include <QTextEdit>
                        #include <QVBoxLayout>
                        #include <QWidget>
                        #include <QWindow>
                        
                        class Popup : public QFrame
                        {
                        public:
                            Popup()
                                : QFrame(nullptr) // OKE
                                //: QFrame(nullptr, Qt::Popup) // NOT OKE
                                
                            {
                                Setup();
                            }
                        
                            void SetInitialText(const QString& t)
                            {
                                txt->setText(t);
                            }
                        
                        private:
                            void ShowContextMenu(const QPoint& pt)
                            {
                                auto menu = txt->createStandardContextMenu();
                                auto custom = menu->addAction("Formatted copy");
                                connect(custom, &QAction::triggered, this, &Popup::CustomActionTriggered);
                                menu->exec(this->mapToGlobal(pt));
                                delete menu;
                            }
                        
                            void CustomActionTriggered(bool)
                            {
                                qInfo() << "Custom action triggered";
                            }
                        
                            void Setup()
                            {
                                layout = new QVBoxLayout(this);
                                txt = new QTextEdit(this);
                                txt->setContextMenuPolicy(Qt::CustomContextMenu);
                                txt->setFrameShape(QFrame::Box);
                                txt->setFrameShadow(QFrame::Plain);
                                txt->setLineWrapMode(QTextEdit::NoWrap);
                                txt->setReadOnly(true);
                                txt->setTextInteractionFlags(Qt::TextSelectableByMouse);
                                connect(txt, &QTextEdit::customContextMenuRequested,
                                    this, &Popup::ShowContextMenu);
                                layout->addWidget(txt);
                            }
                        
                            QVBoxLayout* layout;
                            QTextEdit* txt;
                        };
                        
                        void CreatePopup()
                        {
                            auto popup = new Popup();
                            popup->setAttribute(Qt::WA_DeleteOnClose);
                            popup->SetInitialText("Some text to display");
                            popup->show();
                        }
                        
                        int main(int argc, char** argv)
                        {
                            QApplication app(argc, argv);
                        
                            QWidget window;
                            QAction* showDialog = new QAction("Show dialog", &window);
                            QObject::connect(showDialog, &QAction::triggered, []{ CreatePopup(); });
                            window.addAction(showDialog);
                            window.setContextMenuPolicy(Qt::ActionsContextMenu);
                        
                            window.show();
                        
                            return app.exec();
                        }
                        
                        1 Reply Last reply
                        0
                        • J Offline
                          J Offline
                          Jakob
                          wrote on 18 Jul 2016, 14:33 last edited by
                          #12

                          I also created a bug report for this, as I'm getting more and more convinced it really is a bug, see https://bugreports.qt.io/browse/QTBUG-54820

                          1 Reply Last reply
                          0
                          • S Offline
                            S Offline
                            SGaist
                            Lifetime Qt Champion
                            wrote on 18 Jul 2016, 21:19 last edited by
                            #13

                            Thanks !

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

                            J 1 Reply Last reply 12 Sept 2016, 12:32
                            0
                            • S SGaist
                              18 Jul 2016, 21:19

                              Thanks !

                              J Offline
                              J Offline
                              Jakob
                              wrote on 12 Sept 2016, 12:32 last edited by
                              #14

                              @SGaist According to comments in the bug report the posted code should work in qt 5.6.1, and I have been able to verify this is indeed the case. So I guess I should consider this question as 'answered' then. Thanx for the help

                              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