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. How to activate keyboard shortcut in QMenu
Forum Updated to NodeBB v4.3 + New Features

How to activate keyboard shortcut in QMenu

Scheduled Pinned Locked Moved Solved General and Desktop
14 Posts 4 Posters 3.6k Views 2 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.
  • dporobicD Offline
    dporobicD Offline
    dporobic
    wrote on last edited by dporobic
    #1

    I have QTabWidget that shows some tabs, now I have added a QMenu that works as a right click Context Menu on those tabs (close tab, close other tabs ...). One of the actions in the QMenu has a keyboard shortcut and it's shown in the menu but I can't activate it, no mater if the menu is shown or not. The primary goal is to have the shortcut work when the QMenu is not shown.

    This is my ContextMenu Class (only the relevant stuff):

    AnnotationTabContextMenu::AnnotationTabContextMenu(QWidget *parent)
    	: QMenu(parent),
    	  mCloseTab(new QAction(this))
    {
    	mCloseTab->setText(tr("Close"));
            mCloseTab->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_F4));
    
    	connect(mCloseTab, &QAction::triggered, this, &AnnotationTabContextMenu::closeTabTriggered);
    
    	addAction(mCloseTab);
    }
    
    AnnotationTabContextMenu::~AnnotationTabContextMenu()
    {
    	delete mCloseTab;
    }
    
    void AnnotationTabContextMenu::show(int tabIndex, const QPoint &pos)
    {
    	mTabIndex = tabIndex;
    	exec(pos);
    }
    
    void AnnotationTabContextMenu::closeTabTriggered() const
    {
    	emit closeTab(mTabIndex);
    }
    

    And here is use it (only the relevant stuff):

    AnnotationTabWidget::AnnotationTabWidget() :
    	mTabBar(tabBar()),
    	mTabContextMenu(new AnnotationTabContextMenu(this))
    {
    	setTabsClosable(true);
    	mTabBar->setContextMenuPolicy(Qt::CustomContextMenu);
    
    	connect(mTabBar, &QTabBar::customContextMenuRequested, this, &AnnotationTabWidget::showTabContextMenu);
    	connect(mTabContextMenu, &AnnotationTabContextMenu::closeTab, this, &AnnotationTabWidget::tabCloseRequested);
    }
    
    void AnnotationTabWidget::showTabContextMenu(const QPoint &pos)
    {
    	if (!pos.isNull()) {
    		int tabIndex = mTabBar->tabAt(pos);
    		mTabContextMenu->show(tabIndex, mTabBar->mapToGlobal(pos));
    	}
    }
    

    Any idea what could be preventing the shortcut from being triggered?

    https://github.com/ksnip/ksnip

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

      Hi,

      IIRC, you should add the action to your main widget using the addAction method.

      If you have centralized actions that can be found in several places, you should also centralize their creation and propagate them as needed. Or provide an accessor like QDockWidget's toggleViewAction.

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

      Pl45m4P dporobicD 2 Replies Last reply
      1
      • dporobicD dporobic

        I have QTabWidget that shows some tabs, now I have added a QMenu that works as a right click Context Menu on those tabs (close tab, close other tabs ...). One of the actions in the QMenu has a keyboard shortcut and it's shown in the menu but I can't activate it, no mater if the menu is shown or not. The primary goal is to have the shortcut work when the QMenu is not shown.

        This is my ContextMenu Class (only the relevant stuff):

        AnnotationTabContextMenu::AnnotationTabContextMenu(QWidget *parent)
        	: QMenu(parent),
        	  mCloseTab(new QAction(this))
        {
        	mCloseTab->setText(tr("Close"));
                mCloseTab->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_F4));
        
        	connect(mCloseTab, &QAction::triggered, this, &AnnotationTabContextMenu::closeTabTriggered);
        
        	addAction(mCloseTab);
        }
        
        AnnotationTabContextMenu::~AnnotationTabContextMenu()
        {
        	delete mCloseTab;
        }
        
        void AnnotationTabContextMenu::show(int tabIndex, const QPoint &pos)
        {
        	mTabIndex = tabIndex;
        	exec(pos);
        }
        
        void AnnotationTabContextMenu::closeTabTriggered() const
        {
        	emit closeTab(mTabIndex);
        }
        

        And here is use it (only the relevant stuff):

        AnnotationTabWidget::AnnotationTabWidget() :
        	mTabBar(tabBar()),
        	mTabContextMenu(new AnnotationTabContextMenu(this))
        {
        	setTabsClosable(true);
        	mTabBar->setContextMenuPolicy(Qt::CustomContextMenu);
        
        	connect(mTabBar, &QTabBar::customContextMenuRequested, this, &AnnotationTabWidget::showTabContextMenu);
        	connect(mTabContextMenu, &AnnotationTabContextMenu::closeTab, this, &AnnotationTabWidget::tabCloseRequested);
        }
        
        void AnnotationTabWidget::showTabContextMenu(const QPoint &pos)
        {
        	if (!pos.isNull()) {
        		int tabIndex = mTabBar->tabAt(pos);
        		mTabContextMenu->show(tabIndex, mTabBar->mapToGlobal(pos));
        	}
        }
        

        Any idea what could be preventing the shortcut from being triggered?

        Pl45m4P Offline
        Pl45m4P Offline
        Pl45m4
        wrote on last edited by Pl45m4
        #2

        @dporobic said in How to activate keyboard shortcut in QMenu:

        One of the actions in the QMenu has a keyboard shortcut and it's shown in the menu but I can't activate it, no mater if the menu is shown or not

        Triggering the action with your mouse works?!
        Check your ShortcutContext and which widget has focus / is active while pressing the key sequence.


        If debugging is the process of removing software bugs, then programming must be the process of putting them in.

        ~E. W. Dijkstra

        1 Reply Last reply
        0
        • dporobicD Offline
          dporobicD Offline
          dporobic
          wrote on last edited by
          #3

          Yes, clicking works of course.

          I have tested setting ShortcutContext on the QAction to Qt::WidgetWithChildrenShortcut, Qt::WindowShortcut and Qt::ApplicationShortcut, no change.

          Why is the focus relevant? I was aiming for a Application wide shortcut or at least when the focus is on the QTabWidget should it be possible to trigger it. Sorry if that wasn't clear, I'll update my initial post.

          https://github.com/ksnip/ksnip

          JonBJ Pl45m4P 2 Replies Last reply
          0
          • dporobicD dporobic

            Yes, clicking works of course.

            I have tested setting ShortcutContext on the QAction to Qt::WidgetWithChildrenShortcut, Qt::WindowShortcut and Qt::ApplicationShortcut, no change.

            Why is the focus relevant? I was aiming for a Application wide shortcut or at least when the focus is on the QTabWidget should it be possible to trigger it. Sorry if that wasn't clear, I'll update my initial post.

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

            @dporobic
            I just wondered whether it's worth trying your code with a simpler shortcut, not involving Ctrl or a function key, just in case? Also, you're not on a Mac, are you? Probably this is not the issue, but while you're awaiting a better response....

            1 Reply Last reply
            0
            • dporobicD dporobic

              Yes, clicking works of course.

              I have tested setting ShortcutContext on the QAction to Qt::WidgetWithChildrenShortcut, Qt::WindowShortcut and Qt::ApplicationShortcut, no change.

              Why is the focus relevant? I was aiming for a Application wide shortcut or at least when the focus is on the QTabWidget should it be possible to trigger it. Sorry if that wasn't clear, I'll update my initial post.

              Pl45m4P Offline
              Pl45m4P Offline
              Pl45m4
              wrote on last edited by Pl45m4
              #5

              @dporobic said in How to activate keyboard shortcut in QMenu:

              Why is the focus relevant?

              Because you can have the same shortcuts on multiple widgets (some key sequences get intercepted by OS e.g. Alt +F4, Ctrl + C). So you could use shortcut A while MainWindow or some child window has focus (Window- or App-Shortcut), to do something and use the same key sequence A (as Widget shortcut) to activate another action while a specific widget has focus.

              @dporobic said in How to activate keyboard shortcut in QMenu:

              I was aiming for a Application wide shortcut or at least when the focus is on the QTabWidget should it be possible to trigger it.

              Then use Qt::ApplicationShortcut at least. But make sure that your key sequence is not used for something else (OS or some other widgets). Try another, simple key (e.g. QKeySequence(Qt::Key_F)), like @JonB wrote.
              If the widget / window where your QTabWidget is in, is active, the Window shortcut should work too.


              If debugging is the process of removing software bugs, then programming must be the process of putting them in.

              ~E. W. Dijkstra

              1 Reply Last reply
              1
              • dporobicD Offline
                dporobicD Offline
                dporobic
                wrote on last edited by dporobic
                #6

                I did try Qt:ALT + Qt::Key_H before, will try with a single letter then. No, not a Mac, Windows and Linux, tested on both, not working.

                https://github.com/ksnip/ksnip

                1 Reply Last reply
                0
                • dporobicD Offline
                  dporobicD Offline
                  dporobic
                  wrote on last edited by
                  #7

                  Tested now with all for ShortcutContext and setting the shortcut to a simple Letter, tried H and F, nothing. What I really find strange is even with the menu open, nothing happens:

                  mCloseTab->setText(tr("Close"));
                  mCloseTab->setShortcut(QKeySequence(Qt::Key_F));
                  mCloseTab->setShortcutContext(Qt::ApplicationShortcut);
                  

                  ee05c08d-3136-4485-93af-18f66e4a6d29-image.png

                  https://github.com/ksnip/ksnip

                  1 Reply Last reply
                  0
                  • dporobicD Offline
                    dporobicD Offline
                    dporobic
                    wrote on last edited by
                    #8

                    Interesting, I've created a QToolButton in the ContextMenu, just created it and gave it the same QAction as the defaultAction and now it's triggered when the ContextMenu is open:

                    mCloseTab->setText(tr("Close"));
                    mCloseTab->setShortcut(QKeySequence(Qt::Key_F));
                    mCloseTab->setShortcutContext(Qt::ApplicationShortcut);
                    
                    auto button = new QToolButton(this);
                    button->setDefaultAction(mCloseTab);
                    

                    94658b3d-86fb-4ade-8877-1c69f06762dc-image.png

                    Still not working when the menu is closed.

                    https://github.com/ksnip/ksnip

                    1 Reply Last reply
                    0
                    • dporobicD Offline
                      dporobicD Offline
                      dporobic
                      wrote on last edited by
                      #9

                      Giving the QToolButton the QTabWidget as parent seems to be working even with the menu not shown. Just giving the QAction the QTabWidget as parent doesn't work without the QToolButton.

                      mCloseTab->setText(tr("Close"));
                      mCloseTab->setShortcut(QKeySequence(Qt::Key_F));
                      mCloseTab->setShortcutContext(Qt::ApplicationShortcut);
                      
                      auto button = new QToolButton(parent);
                      button->setDefaultAction(mCloseTab);
                      button->setFixedSize(0,0);
                      

                      It's a workaround, but one of the ugly kind. Any idea how to fix this? Is this a bug?

                      https://github.com/ksnip/ksnip

                      Pl45m4P 1 Reply Last reply
                      0
                      • dporobicD dporobic

                        Giving the QToolButton the QTabWidget as parent seems to be working even with the menu not shown. Just giving the QAction the QTabWidget as parent doesn't work without the QToolButton.

                        mCloseTab->setText(tr("Close"));
                        mCloseTab->setShortcut(QKeySequence(Qt::Key_F));
                        mCloseTab->setShortcutContext(Qt::ApplicationShortcut);
                        
                        auto button = new QToolButton(parent);
                        button->setDefaultAction(mCloseTab);
                        button->setFixedSize(0,0);
                        

                        It's a workaround, but one of the ugly kind. Any idea how to fix this? Is this a bug?

                        Pl45m4P Offline
                        Pl45m4P Offline
                        Pl45m4
                        wrote on last edited by
                        #10

                        @dporobic

                        Looks like there is something wrong with shortcuts and contextMenus in general (I dont know if bug or if we dont use it correctly).
                        Your hierarchy is somewhat like this:

                        • Top level window / MainWindow
                          • TabWidget
                            • TabWidgets TabBar
                            • ContextMenu
                              • Action with shortcut

                        And here is the problem... You can't say if the action actually receives the key event / shortcut, due to multiple parents and children.

                        At least on Window Ctrl + F4 is used (Shortcut List).


                        If debugging is the process of removing software bugs, then programming must be the process of putting them in.

                        ~E. W. Dijkstra

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

                          Hi,

                          IIRC, you should add the action to your main widget using the addAction method.

                          If you have centralized actions that can be found in several places, you should also centralize their creation and propagate them as needed. Or provide an accessor like QDockWidget's toggleViewAction.

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

                          Pl45m4P dporobicD 2 Replies Last reply
                          1
                          • SGaistS SGaist

                            Hi,

                            IIRC, you should add the action to your main widget using the addAction method.

                            If you have centralized actions that can be found in several places, you should also centralize their creation and propagate them as needed. Or provide an accessor like QDockWidget's toggleViewAction.

                            Pl45m4P Offline
                            Pl45m4P Offline
                            Pl45m4
                            wrote on last edited by
                            #12

                            @SGaist

                            But why are these actions and shortcuts in contextMenus possible, if you can not trigger them, even when parent widget has focus or is the only widget? What is the use case for this?


                            If debugging is the process of removing software bugs, then programming must be the process of putting them in.

                            ~E. W. Dijkstra

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

                              Because it would not make sense to have that restriction because you can build these menus and actions in several different ways and that Qt cannot know that you are actually on purpose adding a shortcut to an action that will only be available in a popup menu.

                              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
                              0
                              • SGaistS SGaist

                                Hi,

                                IIRC, you should add the action to your main widget using the addAction method.

                                If you have centralized actions that can be found in several places, you should also centralize their creation and propagate them as needed. Or provide an accessor like QDockWidget's toggleViewAction.

                                dporobicD Offline
                                dporobicD Offline
                                dporobic
                                wrote on last edited by dporobic
                                #14

                                @SGaist said in How to activate keyboard shortcut in QMenu:

                                IIRC, you should add the action to your main widget using the addAction method.

                                The addAction method on the parent seems to be working indeed, need to think about if I should distribute them differently:

                                mCloseTab->setText(tr("Close"));
                                mCloseTab->setShortcut(QKeySequence(Qt::Key_F));
                                mCloseTab->setShortcutContext(Qt::ApplicationShortcut);
                                
                                parent->addAction(mCloseTab);
                                

                                @Pl45m4 it is indeed a close action though it looks like I should be using Ctrl+W which is more cross platform.

                                https://github.com/ksnip/ksnip

                                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