Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Update: Forum Guidelines & Code of Conduct


    Qt World Summit: Early-Bird Tickets

    How to change QMenu behavior

    General and Desktop
    qmenu qdialog qaction qtoolbar
    2
    10
    4321
    Loading More Posts
    • 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.
    • T
      tema_tema last edited by tema_tema

      Hi, I'm a bit stuck with quite specific problem and will appreciate any suggestions.
      First of all I'd like to say that I'm developing small module in the big project, so I can't change some basic things and have to deal with it.
      So, this project is big cross-platform application which has a variety of features and some of them are presented in a big toolbar. My target is to add a couple of buttons in it and provide them needed functionality.

      Main requirements are:

      • button must be checkable;
      • button must have dropdown menu;
      • it must be icon with small arrow on the right side (as it usually appears in applications).

      It looks like quite easy: we can take QAction, add it to toolbar, create QMenu, pack it with some other QActions and set this menu for QAction from toolbar.

      But the problem is that dropdown menu must have specific view and it already designed and developed, and it is presented as QDialog. So, when I click the black arrow near the icon in toolbar this QDialog should appear.

      For now I have found following solution:

      1. Create my own QCustomMenu class which is inherited from QMenu.
      2. In this custom class override showEvent(...) method.
      3. Create QAction, add it to toolbar.
      4. Create object of my custom menu class and insert it as a menu for this QAction.
      5. Connect to aboutToShow() signal of my custom menu.
      6. In connected slot exec() given QDialog and perform all needed actions.

      This is how my custom class looks like:

      class QCustomMenu : public QMenu
      {
      Q_OBJECT
      public:
      QCustomMenu(QObject *parent = 0){};
      void showEvent(QShowEvent *)
      {
      this->hide(); // close() also possible
      }
      };

      In Windows it works great and performs as I expected.

      But in Linux here's a small problem: when I press button in created QDialog and it disappears I can't press any button in the whole application (but when I hover mouse to icons in toolbar their description appears in status bar and so on, they are simply unclickable ). It looks like QCustomMenu wasn't closed or smth like that, but I can't catch what I have missed. May be I should override other events or something else. I have been trying to figure it out for three days now and absolutely stuck (it looks like that QMenu perform different with X11 ) .
      Everything I want is to close this QCustomMenu programmatically when it try to appear.
      Hope someone could help me with some good suggestions.

      1 Reply Last reply Reply Quote 0
      • SGaist
        SGaist Lifetime Qt Champion last edited by

        Hi and welcome to devnet,

        Since you don't use it at all, why the QMenu ?
        Why not connect the triggered signal of your action to a custom slot that would show your dialog ?

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

        T 1 Reply Last reply Reply Quote 0
        • T
          tema_tema @SGaist last edited by tema_tema

          @SGaist the problem is that I need this toolbar button being able to press (or check like on/off state) that's why I can't do it in this way.

          1 Reply Last reply Reply Quote 0
          • SGaist
            SGaist Lifetime Qt Champion last edited by

            A checkable QAction ?

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

            T 1 Reply Last reply Reply Quote 0
            • T
              tema_tema @SGaist last edited by

              @SGaist yes, when you add a QAction into QToolBar you can set it checkable and if you press it you will see the button which represents QAction being hold in the toolbar.
              For example, in this picture "align left" button is checked in the QAction meaning.
              picture

              1 Reply Last reply Reply Quote 0
              • SGaist
                SGaist Lifetime Qt Champion last edited by

                Before going further, what do you need to show in that dialog ?

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

                T 1 Reply Last reply Reply Quote 0
                • T
                  tema_tema @SGaist last edited by

                  @SGaist actually it is some kind of a treeview with a bunch of buttons, due to specifications I need to use only this dialog.

                  1 Reply Last reply Reply Quote 0
                  • SGaist
                    SGaist Lifetime Qt Champion last edited by

                    Then I'd rather go with a checkable action, show the dialog in triggered(true) and hide it again on triggered(false)

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

                    T 1 Reply Last reply Reply Quote 0
                    • T
                      tema_tema @SGaist last edited by

                      @SGaist unfortunately, i don't have an option. I have to show given dialog.

                      1 Reply Last reply Reply Quote 0
                      • T
                        tema_tema last edited by tema_tema

                        For now I found following solution to prevent GUI from freeze:

                        {
                        Q_OBJECT
                        public:
                        QCustomMenu(QObject *parent = 0){};
                        void showEvent(QShowEvent *)
                        {
                        emit show();
                        QMenu::closeEvent(new QCloseEven());
                        QMenu::hideEvent(new QHideEvent());
                        }
                        signals:
                        void show();
                        };
                        

                        And also now I've changed logic: on show() signal I exec() my dialog:

                        QCustomMenu *menu = new QCustomMenu(toolbar);
                        connect(menu, SIGNAL(show()), this, SLOT(execMyMenu()));
                        

                        But after closing my dialog UI waits for mouse click somewhere to start responding for further actions.

                        May be it is possible to make programmatically click somewhere ? I didn't find any solution yet.

                        1 Reply Last reply Reply Quote 0
                        • First post
                          Last post