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. Possible to allow QShortcut to work with modal QDialogs ?
Qt 6.11 is out! See what's new in the release blog

Possible to allow QShortcut to work with modal QDialogs ?

Scheduled Pinned Locked Moved Solved General and Desktop
7 Posts 3 Posters 2.0k 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.
  • mrjjM Offline
    mrjjM Offline
    mrjj
    Lifetime Qt Champion
    wrote on last edited by mrjj
    #1

    Hi
    I was wondering if anyone knew a trick to get a true app wide global hotkey.
    The following works until modal dialog is shown.

    I understand its correct to block all events as it does - but outside
    of assigning same shortcut to all dialog/re- parent or using event filters on QApp,

    is there another way to make it work ?
    I tried not assigning parent just in case it would belong to QApp instead.

    // this = mainwindow
     QShortcut* shortcut = new QShortcut( QKeySequence(Qt::AltModifier + Qt::Key_X), this); 
      shortcut->setContext(Qt::ApplicationShortcut);
      QObject::connect(shortcut, &QShortcut::activated, [this]() {
       ....
      });
    
    1 Reply Last reply
    0
    • Gojir4G Offline
      Gojir4G Offline
      Gojir4
      wrote on last edited by
      #2

      Hi @mrjj ,

      The simplest solution I can see is to re-assign parent when showing the dialog. It requires to keep all shortcuts in a list but avoids re-creating them. Hope that's not what you meant with "assigning same shortcuts to all dialog".

      //.h
      QList<QShortcut *> m_shortcuts;
      
      // MainWindow constructor
       QShortcut* shortcut = new QShortcut( QKeySequence(Qt::AltModifier + Qt::Key_Y), this);
          shortcut->setContext(Qt::ApplicationShortcut);
          QObject::connect(shortcut, &QShortcut::activated, [this]() {
              qDebug() << "Shortcut ALT + Y activated ";
          });
          m_shortcuts.append(shortcut);
      
          shortcut = new QShortcut( QKeySequence(Qt::AltModifier + Qt::Key_X), this);
          shortcut->setContext(Qt::ApplicationShortcut);
          QObject::connect(shortcut, &QShortcut::activated, []() {
              qDebug() << "Shortcut ALT + X activated ";
          });
      
          m_shortcuts.append(shortcut);
      
      void MainWindow::showModalDialog()
      {
          QDialog *dialog = new QDialog(this);
          for(QShortcut *s : m_shortcuts){
              s->setParent(dialog);
          }
      
          dialog->exec();
      
          for(QShortcut *s : m_shortcuts){
              s->setParent(this);
          }
      }
      
      mrjjM JonBJ 2 Replies Last reply
      3
      • Gojir4G Gojir4

        Hi @mrjj ,

        The simplest solution I can see is to re-assign parent when showing the dialog. It requires to keep all shortcuts in a list but avoids re-creating them. Hope that's not what you meant with "assigning same shortcuts to all dialog".

        //.h
        QList<QShortcut *> m_shortcuts;
        
        // MainWindow constructor
         QShortcut* shortcut = new QShortcut( QKeySequence(Qt::AltModifier + Qt::Key_Y), this);
            shortcut->setContext(Qt::ApplicationShortcut);
            QObject::connect(shortcut, &QShortcut::activated, [this]() {
                qDebug() << "Shortcut ALT + Y activated ";
            });
            m_shortcuts.append(shortcut);
        
            shortcut = new QShortcut( QKeySequence(Qt::AltModifier + Qt::Key_X), this);
            shortcut->setContext(Qt::ApplicationShortcut);
            QObject::connect(shortcut, &QShortcut::activated, []() {
                qDebug() << "Shortcut ALT + X activated ";
            });
        
            m_shortcuts.append(shortcut);
        
        void MainWindow::showModalDialog()
        {
            QDialog *dialog = new QDialog(this);
            for(QShortcut *s : m_shortcuts){
                s->setParent(dialog);
            }
        
            dialog->exec();
        
            for(QShortcut *s : m_shortcuts){
                s->setParent(this);
            }
        }
        
        mrjjM Offline
        mrjjM Offline
        mrjj
        Lifetime Qt Champion
        wrote on last edited by mrjj
        #3

        @Gojir4
        Hi
        Sadly it was what i meant with "assigning same shortcuts to all dialog". :)
        i should have said re-parenting.

        While idea is good, its not very practical in my use case as a dialog can also pop dialog and so on
        so having to loop the m_shortcuts all places where a dialog is born is a bit cumbersome even
        i do have a makeDialog function so its somewhat under control but it would also need access to m_shortcuts list.

        I saw someone using eventfilter . i think i will go down that road if i really want it.

        Its no critical and i posted just make sure i was not missing something obvious.
        like shortcut->setIgnoreModal kinda -ish :)

        JonBJ 1 Reply Last reply
        0
        • Gojir4G Gojir4

          Hi @mrjj ,

          The simplest solution I can see is to re-assign parent when showing the dialog. It requires to keep all shortcuts in a list but avoids re-creating them. Hope that's not what you meant with "assigning same shortcuts to all dialog".

          //.h
          QList<QShortcut *> m_shortcuts;
          
          // MainWindow constructor
           QShortcut* shortcut = new QShortcut( QKeySequence(Qt::AltModifier + Qt::Key_Y), this);
              shortcut->setContext(Qt::ApplicationShortcut);
              QObject::connect(shortcut, &QShortcut::activated, [this]() {
                  qDebug() << "Shortcut ALT + Y activated ";
              });
              m_shortcuts.append(shortcut);
          
              shortcut = new QShortcut( QKeySequence(Qt::AltModifier + Qt::Key_X), this);
              shortcut->setContext(Qt::ApplicationShortcut);
              QObject::connect(shortcut, &QShortcut::activated, []() {
                  qDebug() << "Shortcut ALT + X activated ";
              });
          
              m_shortcuts.append(shortcut);
          
          void MainWindow::showModalDialog()
          {
              QDialog *dialog = new QDialog(this);
              for(QShortcut *s : m_shortcuts){
                  s->setParent(dialog);
              }
          
              dialog->exec();
          
              for(QShortcut *s : m_shortcuts){
                  s->setParent(this);
              }
          }
          
          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on last edited by
          #4

          @Gojir4 , @mrjj

          @Gojir4 May I (politely) enquire whether you have tested this actually works (I don't know)? Because e.g. https://stackoverflow.com/a/4344518/489865 comment states:

          parent must be a pointer to existing widget. One can pass QApplication::desktop() as parent. It is worth to know that modal windows will block shortcuts even with application context.

          which might imply the shortcuts never work with dialogs?

          @mrjj Be aware that this solution does not scale if, say, you have your main dialog invoke a further dialog, which my app has a lot of...

          Gojir4G mrjjM 2 Replies Last reply
          1
          • mrjjM mrjj

            @Gojir4
            Hi
            Sadly it was what i meant with "assigning same shortcuts to all dialog". :)
            i should have said re-parenting.

            While idea is good, its not very practical in my use case as a dialog can also pop dialog and so on
            so having to loop the m_shortcuts all places where a dialog is born is a bit cumbersome even
            i do have a makeDialog function so its somewhat under control but it would also need access to m_shortcuts list.

            I saw someone using eventfilter . i think i will go down that road if i really want it.

            Its no critical and i posted just make sure i was not missing something obvious.
            like shortcut->setIgnoreModal kinda -ish :)

            JonBJ Offline
            JonBJ Offline
            JonB
            wrote on last edited by JonB
            #5

            @mrjj said in Possible to allow QShortcut to work with modal QDialogs ?:

            so having to loop the m_shortcuts all places where a dialog is born is a bit cumbersome even
            i do have a makeDialog function so its somewhat under control but it would also need access to m_shortcuts list.

            • Make the m_shortcuts list application-global instead of parent-widget-specific, as that's what you want anyway.

            • If you have derived all your dialogs from your own QDialog-derived-class (you have already done that, haven't you? :) ), put the logic for assigning & restoring the shortcuts in the dialog class instead of requiring the caller to do it? This also solves the nested-dialogs issue.

            1 Reply Last reply
            1
            • JonBJ JonB

              @Gojir4 , @mrjj

              @Gojir4 May I (politely) enquire whether you have tested this actually works (I don't know)? Because e.g. https://stackoverflow.com/a/4344518/489865 comment states:

              parent must be a pointer to existing widget. One can pass QApplication::desktop() as parent. It is worth to know that modal windows will block shortcuts even with application context.

              which might imply the shortcuts never work with dialogs?

              @mrjj Be aware that this solution does not scale if, say, you have your main dialog invoke a further dialog, which my app has a lot of...

              Gojir4G Offline
              Gojir4G Offline
              Gojir4
              wrote on last edited by
              #6

              @mrjj OK, sad indeed :).

              @JonB Yes I have tested it and it works. I usually indicate when I post a code which is not tested or compiled.

              1 Reply Last reply
              2
              • JonBJ JonB

                @Gojir4 , @mrjj

                @Gojir4 May I (politely) enquire whether you have tested this actually works (I don't know)? Because e.g. https://stackoverflow.com/a/4344518/489865 comment states:

                parent must be a pointer to existing widget. One can pass QApplication::desktop() as parent. It is worth to know that modal windows will block shortcuts even with application context.

                which might imply the shortcuts never work with dialogs?

                @mrjj Be aware that this solution does not scale if, say, you have your main dialog invoke a further dialog, which my app has a lot of...

                mrjjM Offline
                mrjjM Offline
                mrjj
                Lifetime Qt Champion
                wrote on last edited by mrjj
                #7

                @JonB

                Yes, i always use a extra GUI base classes so i can add my own polymorphic behavior
                if needed later. (often is)
                So i could hide the loop away in BaseDialog so to speak.
                And just update the docs to tell the other to use Base always.

                Might not be so bad as i first thought :)

                thank you both

                1 Reply Last reply
                4

                • Login

                • Login or register to search.
                • First post
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • Users
                • Groups
                • Search
                • Get Qt Extensions
                • Unsolved