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. [Solved] QAction + QMenu: How to trigger the menu from within the code?
Forum Updated to NodeBB v4.3 + New Features

[Solved] QAction + QMenu: How to trigger the menu from within the code?

Scheduled Pinned Locked Moved General and Desktop
10 Posts 3 Posters 10.8k 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.
  • T Offline
    T Offline
    thEClaw
    wrote on last edited by
    #1

    You can set a popup-menu for a QAction (e.g. for when it is in a toolbar) via "QAction::setMenu":http://qt-project.org/doc/qt-5.1/qtwidgets/qaction.html#setMenu .

    In my case the action itself is pretty useless, so I want the menu to show up even when the action is triggered, not only that little arrow next to it. Just calling exec() for its menu doesn't position it properly, though. Is there some way to either get the global position of the action, or directly trigger that arrow (I assume that's a QAction on its own)?

    1 Reply Last reply
    0
    • T Offline
      T Offline
      tanmay2227
      wrote on last edited by
      #2

      menu.exec(event->globalPos());
      use this command it will position the menu at the point of click

      Tanmay Priyadarshi

      1 Reply Last reply
      0
      • T Offline
        T Offline
        thEClaw
        wrote on last edited by
        #3

        Sorry, but that doesn't help. I don't have an event, and even if I had: globalPos() is not the correct position. If I click the little menu-arrow next to the action, it is positioned exactly where you would expect it. And that position is not the same as globalPos() in nearly all cases.

        And just to be clear: I tried using QCursor::pos(), but it has the same problems event->globalPos() has.

        1 Reply Last reply
        0
        • T Offline
          T Offline
          tanmay2227
          wrote on last edited by
          #4

          well i actually used a context menu event and it works in that case so maybe it is for that only

          Tanmay Priyadarshi

          1 Reply Last reply
          0
          • raven-worxR Offline
            raven-worxR Offline
            raven-worx
            Moderators
            wrote on last edited by
            #5

            when i understood you right you want to open the sub-menu on click on the action. So no event and no position is involved.

            But why do you want to do this? This is against the default behavior and may not be what the user expects.
            And as you said the action is useless in the first place, why do you want it to be included at all then?

            --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
            If you have a question please use the forum so others can benefit from the solution in the future

            1 Reply Last reply
            0
            • T Offline
              T Offline
              thEClaw
              wrote on last edited by
              #6

              The action itself is useless, it's popup-menu isn't. So I want the action to trigger said menu, like the small arrow next to the action does.

              1 Reply Last reply
              0
              • raven-worxR Offline
                raven-worxR Offline
                raven-worx
                Moderators
                wrote on last edited by
                #7

                sry..my fault...i thought we are talking about a context menu.

                What happens when you do this (once after you've added the action to the toolbar):
                @
                QWidget * widget = toolBar->widgetForAction ( action );
                QToolButton* button = qobject_cast<QToolButton*>(widget);
                if( button )
                {
                connect( action, SIGNAL(triggered(bool)), button, SLOT(showMenu()) );
                }
                @

                --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
                If you have a question please use the forum so others can benefit from the solution in the future

                1 Reply Last reply
                1
                • T Offline
                  T Offline
                  thEClaw
                  wrote on last edited by
                  #8

                  The action is added dynamically, so I can't really pinpoint when or where it is added.
                  To me this feels like an insufficiency of Qt, since every action has a trigger() slot, but not a "showMenu()" slot (in case it has a menu).

                  Is there any other "standard behavior" I could implement for the action? As it is now, it looks like button, it acts like a button, but it doesn't do anything.

                  1 Reply Last reply
                  0
                  • raven-worxR Offline
                    raven-worxR Offline
                    raven-worx
                    Moderators
                    wrote on last edited by
                    #9

                    [quote author="thEClaw" date="1381844627"]
                    To me this feels like an insufficiency of Qt, since every action has a trigger() slot, but not a "showMenu()" slot (in case it has a menu).[/quote]
                    Not in my opinion. The QAction design is abstract. The specific behavior depends on how you visualize the action. The action is displayed as a QToolButton in a QToolBar. And as an menu item in QMenu.

                    Ok ... other approach then. Subclass QToolBar and reimplement the actionEvent() handler.
                    @
                    void MyToolBar::actionEvent( QActionEvent* event )
                    {
                    QToolBar::actionEvent(event);

                    if( event->type() == QEvent::ActionAdded )
                    {
                         QAction* action = event->action();
                         QWidget * widget = toolBar->widgetForAction ( action );
                         QToolButton* button = qobject_cast<QToolButton*>(widget);
                         if( button )
                         {
                              connect( action, SIGNAL(triggered(bool)), button, SLOT(showMenu()) );
                          }
                    }
                    

                    }
                    @

                    If you only want to do this for a specific action you can set a property to the action and check for the property before doing the connection, or use QAction's data-property.

                    --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
                    If you have a question please use the forum so others can benefit from the solution in the future

                    1 Reply Last reply
                    0
                    • T Offline
                      T Offline
                      thEClaw
                      wrote on last edited by
                      #10

                      That idea was great, thanks a lot!

                      I did the connection like this in the end:
                      @connect(button, &QToolButton::clicked, button, &QToolButton::showMenu);@

                      since the action may be part of different widgets, but overall this seems to work great. Thanks once more, on to the next problem! ;)

                      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