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]Priority of QKeySequence over keyPressEvent
Qt 6.11 is out! See what's new in the release blog

[Solved]Priority of QKeySequence over keyPressEvent

Scheduled Pinned Locked Moved General and Desktop
18 Posts 3 Posters 13.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.
  • J Offline
    J Offline
    JulienMaille
    wrote on last edited by
    #1

    Dear Qt-ers,
    I need to bind the Return key to a QAction. I have done this with
    @actionStartMeasure->setShortcut(Qt::Key_Return);@ Now I have some side-effects with both standard and custom widget.
    If the user press Enter when a QComboBox has focus, it will select the current entry in the combobox and trigger the QAction.
    If I create a new widget and reimplement keyPressEvent(), I never enter this function it when the Enter key is pressed.

    How can I deal with that. Is there some place where the priorities of shortcut handling are explained?
    I see I have a 3rd option: creating a QShortcut and connecting it to my QAction. Again: how are priorities handled?

    1 Reply Last reply
    0
    • S Offline
      S Offline
      Sam
      wrote on last edited by
      #2

      How about using an eventFilter() for your applicaiton where you can set newWidget->installEventFilters(this) and you can check based on the target value eg.

      @bool MainWindow::eventFilter(QObject *target, QEvent *event)
      {
      if (target == newWidget && event->type() == QEvent::KeyPress)
      {
      QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
      if (keyEvent->key() == Qt::Key_Enter || keyEvent->key() == Qt::Key_Return)
      {
      //do something
      return QMainWindow::eventFilter(target,event);
      }
      }
      return QMainWindow::eventFilter(target,event);
      }@

      1 Reply Last reply
      0
      • J Offline
        J Offline
        JulienMaille
        wrote on last edited by
        #3

        -This way, i would not catch all the "Enter" events that have been accepted by child widgets?-
        Hum sorry I read too quickly.
        I don't understand: which widgets do you suggest me to install this filter on?

        1 Reply Last reply
        0
        • S Offline
          S Offline
          Sam
          wrote on last edited by
          #4

          You can install the eventFilter on your custom widget.

          bq. If I create a new widget and reimplement keyPressEvent(), I never enter this function it when the Enter key is pressed.

          For an example you can check "here":http://qt-project.org/doc/qt-5.0/qtcore/qobject.html#eventFilter

          1 Reply Last reply
          0
          • J Offline
            J Offline
            JulienMaille
            wrote on last edited by
            #5

            I know how to install events. Other keystroke do work. The problem occurs with the "Return" key that is somehow eaten by the global shortcut. With your suggestion, you think I can keep my global shorcut and still receive "enter" event on my custom widget? I will try but I don't think so.
            Will end up with the same problem than when reimplementing keyPressEvent, won't I?

            1 Reply Last reply
            0
            • J Offline
              J Offline
              JulienMaille
              wrote on last edited by
              #6

              Still struggling with that question.

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

                i think you need to listen to the QEvent::ShortcutOverride event (which is a QKeyEvent) and trigger your action manually.
                Did you additionally set a shortcut context of the shortcut set on your action?

                --- 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
                • J Offline
                  J Offline
                  JulienMaille
                  wrote on last edited by
                  #8

                  Thanks a lot for your answer.
                  I played with shortcut context on my QAction, but it only work as intended with the default value.
                  I will have a look at your suggestion.
                  So you are telling me that my widget (in this case the QLineEdit) will receive a ShortcutOverride event when the Return key is pressed?
                  Or that I should remove my "global" shortcut and listen to ShortcutOverride on the mainwindow instead?

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

                    You will only receive a ShortcutOverride event when there is a shortcut disambiguation.
                    If no disambiguation is detected a normal shortcut event is sent and the action is triggered normally (as one would expected).
                    Note: ShortcutOverride events aren't handled in Qt by default.

                    I'm not 100% sure if your line edit will receive the shortcut override event, but i think so. At least it would make sense IMHO.
                    But to make sure you can install an event filter on the QApplication and check which widget receives the shortcut override event initially.

                    --- 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
                    • J Offline
                      J Offline
                      JulienMaille
                      wrote on last edited by
                      #10

                      Cool, that did the trick when I installed it on my QLineEdit.
                      Would be could if I could install it once on the QMainWindow and check if the receiver is a QSpinBox, QComboBox or QLineEdit.
                      However when I try that, the object returned in
                      @eventFilter(QObject *obj, QEvent *event)@ is always a QMainWindow

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

                        did you install the main window on the widgets you want to inspect as an event filter?
                        Alternatively as i said you can install the main window on the QApplication object and check there if the watched is one of your widgets.
                        @qApp->installEventFilter(mainWin);@

                        --- 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
                        • J Offline
                          J Offline
                          JulienMaille
                          wrote on last edited by
                          #12

                          Ok in the mean time I tried to install in on the qApp instead of the QMainWindow.
                          I now enter the eventFilter for all successive widgets that sees the keypressEvent propagation.
                          How do I stop this propagation? Returning true does not stop it.
                          @bool ApplicationMonitor::eventFilter(QObject *obj, QEvent *event)
                          {
                          if (event->type() == QEvent::ShortcutOverride )
                          {
                          QKeyEvent *ev = static_cast<QKeyEvent *>(event);
                          if( ev->key()==Qt::Key_Return || ev->key()==Qt::Key_Enter )
                          {
                          qTrace(obj->metaObject()->className());
                          return true;
                          }
                          }
                          // standard event processing
                          return QObject::eventFilter(obj, event);
                          };@
                          [quote]TRACE 19/04/13 12:07:33 - QDoubleSpinBox
                          TRACE 19/04/13 12:07:35 - QWidget
                          TRACE 19/04/13 12:07:35 - QDockWidget
                          TRACE 19/04/13 12:07:35 - MainWindows[/quote]

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

                            @event->accept() //stops event propagation@

                            But in your code you don't check the watched object against your widget objects.

                            --- 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
                            • J Offline
                              J Offline
                              JulienMaille
                              wrote on last edited by
                              #14

                              Thanks again, your help is greatly appreciated! I'm not sure why the doc for eventFilter() says
                              [quote]In your reimplementation of this function, if you want to filter the event out, i.e. stop it being handled further, return true; otherwise return false.[/quote]
                              Should I do both: accept it and return true?

                              If the object is not a QLineEdit, should I return false and reject the event? Or just return false?

                              Last question: In order to filter on receiver what is best in terms of perfomances.
                              @obj->metaObject()->className()=="QLineEdit"
                              QLineEdit* le = dynamic_cast<QLineEdit*>(obj)@

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

                                [quote author="Julien M" date="1366366563"]
                                If the object is not a QLineEdit, should I return false and reject the event? Or just return false?
                                [/quote]
                                Best would be todo nothing of both :)
                                You just want to inspect and trigger your action in case and don't want to manipulate the event chain at all.

                                [quote author="Julien M" date="1366366563"]
                                Last question: In order to filter on receiver what is best in terms of perfomances.
                                @obj->metaObject()->className()=="QLineEdit"
                                QLineEdit* le = dynamic_cast<QLineEdit*>(obj)@[/quote]
                                Best would be to hold pointers to your widgets and jsut do a pointer comparison. Thats the fastest way. Don't use dynamic_cast, only if you really have to, since the it has a large performance impact.

                                --- 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
                                • J Offline
                                  J Offline
                                  JulienMaille
                                  wrote on last edited by
                                  #16

                                  [quote author="raven-worx" date="1366366885"]Best would be todo nothing of both :)
                                  You just want to inspect and trigger your action in case and don't want to manipulate the event chain at all.[/quote]No, in fact what I'm trying to do now is:

                                  • Keep my "Return" QShortcut on a QAction
                                  • Prevent some specific widget types (eg. QLineEdit) to trigger this QAction when the user press Return in them

                                  So my eventFilter won't trigger the action but "forbid triggering in some case" instead.

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

                                    ah yes...sorry.
                                    Nevertheless did you try already try to accept the event and if necessary also return true in the event filter?

                                    --- 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
                                    • J Offline
                                      J Offline
                                      JulienMaille
                                      wrote on last edited by
                                      #18

                                      Finally did that: @event->accept(); // Prevent event propagation to parents
                                      return false; // Allow obj to handle the "Enter" event@

                                      Thanks a lot for your help raven-worx!

                                      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