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. QLineEdit::returnPressed when something else has a Key_Return shortcut
QtWS25 Last Chance

QLineEdit::returnPressed when something else has a Key_Return shortcut

Scheduled Pinned Locked Moved Solved General and Desktop
20 Posts 5 Posters 2.1k Views
  • 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 Online
    J Online
    JonB
    wrote on 20 Mar 2024, 20:42 last edited by
    #6

    BTW, how do these shortcuts and keys work? If the focus is in a widget (which accepts input) that gets to handle it first? Only if it does not accept the key does it get passed upward through the widget hierarchy, and the treatment as a shortcut happens somewhere there?

    And while we are here, is that the same order for mouse presses, bottom to top of the hierarchy? I thought I once saw that key events and mouse events are propagated in the opposite order from each other?

    1 Reply Last reply
    0
    • C Online
      C Online
      Chris Kawa
      Lifetime Qt Champion
      wrote on 20 Mar 2024, 21:05 last edited by Chris Kawa
      #7

      Either subclass and override event() to handle QEvent::ShortcutOverride or install a filter and check for the same. In either case accept() the event and return true when it's the return key. This will override the shortcut and pass the event through to the widget to handle as usual.

      BTW, how do these shortcuts and keys work?

      With no shortcuts involved it's just a bubble up thing - the click goes to whatever was under the cursor and accepts clicks. If you put a "transparent for clicks" flag on a widget the click goes to whatever is under it and so on all the way to the bottom. With buttons it's similar - focused widget gets it first and if it doesn't accept keyboard the event bubbles up through parents until something handles it.

      How shortcuts work depends on the scope. Assuming you have the default window scope when a button is pressed the widget that has focus gets ShortcutOverride event first. If it rejects it (the default) the shortcut swallows the button. If it accepts it the shortcut is overriden and the press is handled as usual i.e. the widget gets a key press event.

      J 1 Reply Last reply 20 Mar 2024, 21:18
      6
      • C Chris Kawa
        20 Mar 2024, 21:05

        Either subclass and override event() to handle QEvent::ShortcutOverride or install a filter and check for the same. In either case accept() the event and return true when it's the return key. This will override the shortcut and pass the event through to the widget to handle as usual.

        BTW, how do these shortcuts and keys work?

        With no shortcuts involved it's just a bubble up thing - the click goes to whatever was under the cursor and accepts clicks. If you put a "transparent for clicks" flag on a widget the click goes to whatever is under it and so on all the way to the bottom. With buttons it's similar - focused widget gets it first and if it doesn't accept keyboard the event bubbles up through parents until something handles it.

        How shortcuts work depends on the scope. Assuming you have the default window scope when a button is pressed the widget that has focus gets ShortcutOverride event first. If it rejects it (the default) the shortcut swallows the button. If it accepts it the shortcut is overriden and the press is handled as usual i.e. the widget gets a key press event.

        J Online
        J Online
        JonB
        wrote on 20 Mar 2024, 21:18 last edited by
        #8

        @Chris-Kawa
        Great stuff. I have plenty to try from all three of you, thanks :)

        1 Reply Last reply
        0
        • J Offline
          J Offline
          jeremy_k
          wrote on 20 Mar 2024, 21:22 last edited by
          #9

          Another option: check for the focus widget in the shortcut's triggered slot.

          Asking a question about code? http://eel.is/iso-c++/testcase/

          1 Reply Last reply
          0
          • J Online
            J Online
            JonB
            wrote on 21 Mar 2024, 13:02 last edited by JonB
            #10

            Morning folks :)

            I took @Chris-Kawa's suggestion of QEvent::ShortcutOverride, which I did not know about and seems to be exactly what I want: just don't let a shortcut on Key_Return activate while focus is in my QLineEdit, then leave return to be acted on by the line edit just as however it does it now. I did it with installEventFilter(). And that worked fine.

            Then, I am a bit of a "purist" in my coding :) I thought about it and decided to subclass QLineEdit and do the same but in its event(). You could argue both ways. But the installEventFilter() requires (a) the parent main window to provide an eventFilter() method for the line edit and (b) the parent to call installEventFilter() on behalf of the line edit. Say I am a junior programmer, tasked with writing the line edit code, but not to bother the senior programmers who look after the main window :) I decided, for right or for wrong, to make it so the line edit behaviour is "self-contained": no matter where it is hosted it does not want to allow a Return shortcut to take that away from itself.

            So final code:

            /*virtual*/ bool SpecialLineEdit::event(QEvent *e) /*override*/
            {
                if (e->type() == QEvent::ShortcutOverride)
                {
                    QKeyEvent *keyEvent = static_cast<QKeyEvent *>(e);
                    if (keyEvent->key() == Qt::Key_Return)
                    {
                        // next line added for correct solation as per @Chris-Kawa's comment below
                        e->accept();
                        return true;
                    }
                }
                return QLineEdit::event(e);
            }
            

            Everyone happy with this? :)

            Thanks to all who participated.

            C 1 Reply Last reply 21 Mar 2024, 19:37
            1
            • J JonB has marked this topic as solved on 21 Mar 2024, 13:02
            • J JonB
              21 Mar 2024, 13:02

              Morning folks :)

              I took @Chris-Kawa's suggestion of QEvent::ShortcutOverride, which I did not know about and seems to be exactly what I want: just don't let a shortcut on Key_Return activate while focus is in my QLineEdit, then leave return to be acted on by the line edit just as however it does it now. I did it with installEventFilter(). And that worked fine.

              Then, I am a bit of a "purist" in my coding :) I thought about it and decided to subclass QLineEdit and do the same but in its event(). You could argue both ways. But the installEventFilter() requires (a) the parent main window to provide an eventFilter() method for the line edit and (b) the parent to call installEventFilter() on behalf of the line edit. Say I am a junior programmer, tasked with writing the line edit code, but not to bother the senior programmers who look after the main window :) I decided, for right or for wrong, to make it so the line edit behaviour is "self-contained": no matter where it is hosted it does not want to allow a Return shortcut to take that away from itself.

              So final code:

              /*virtual*/ bool SpecialLineEdit::event(QEvent *e) /*override*/
              {
                  if (e->type() == QEvent::ShortcutOverride)
                  {
                      QKeyEvent *keyEvent = static_cast<QKeyEvent *>(e);
                      if (keyEvent->key() == Qt::Key_Return)
                      {
                          // next line added for correct solation as per @Chris-Kawa's comment below
                          e->accept();
                          return true;
                      }
                  }
                  return QLineEdit::event(e);
              }
              

              Everyone happy with this? :)

              Thanks to all who participated.

              C Online
              C Online
              Chris Kawa
              Lifetime Qt Champion
              wrote on 21 Mar 2024, 19:37 last edited by
              #11

              @JonB You're missing a call to e->accept() before returning true.

              Also, as a side note, since full keyboard users often use them interchangeably and QLineEdit also supports it, you should probably treat Key_Enter the same way if you want to be safe. And yes, the QLineEdit's signal is called returnPressed, but it is emitted for both Return and Enter.

              J 1 Reply Last reply 21 Mar 2024, 19:47
              3
              • C Chris Kawa
                21 Mar 2024, 19:37

                @JonB You're missing a call to e->accept() before returning true.

                Also, as a side note, since full keyboard users often use them interchangeably and QLineEdit also supports it, you should probably treat Key_Enter the same way if you want to be safe. And yes, the QLineEdit's signal is called returnPressed, but it is emitted for both Return and Enter.

                J Online
                J Online
                JonB
                wrote on 21 Mar 2024, 19:47 last edited by JonB
                #12

                @Chris-Kawa said in QLineEdit::returnPressed when something else has a Key_Return shortcut:

                @JonB You're missing a call to e->accept() before returning true.

                Funny, because I was going to ask about just this but didn't get around to it. I wondered if caller goes

                if (event(e) || e->isAccepted)
                

                but I guess they are different. It works, but doubtless because of default value or something. What is the difference/relationship between return result of event() and setting/clearing accepted, please?

                Will do for Key_Enter. Is that the key on my numeric pad which I have never used once in my life?

                C 1 Reply Last reply 21 Mar 2024, 19:58
                0
                • J JonB
                  21 Mar 2024, 19:47

                  @Chris-Kawa said in QLineEdit::returnPressed when something else has a Key_Return shortcut:

                  @JonB You're missing a call to e->accept() before returning true.

                  Funny, because I was going to ask about just this but didn't get around to it. I wondered if caller goes

                  if (event(e) || e->isAccepted)
                  

                  but I guess they are different. It works, but doubtless because of default value or something. What is the difference/relationship between return result of event() and setting/clearing accepted, please?

                  Will do for Key_Enter. Is that the key on my numeric pad which I have never used once in my life?

                  C Online
                  C Online
                  Chris Kawa
                  Lifetime Qt Champion
                  wrote on 21 Mar 2024, 19:58 last edited by
                  #13

                  What is the difference/relationship between return result of event() and setting/clearing accepted, please?

                  Return value says whether your handler handled the event i.e. if you return false the filter will go to the next guy in the chain. If you return true it stops with you.

                  accept sets a property of the event itself - so anyone getting the pointer can check whether it was accepted.

                  While usually they're set symmetrically you could also reject the event and return true, meaning the event should be ignored and no one else should look at it or you could call accept and return false, meaning you consider the event handled by you, but if anyone else in the chain wants a stab at it they can.

                  Will do for Key_Enter. Is that the key on my numeric pad which I have never used once in my life?

                  Yup, that's the one :)

                  J 1 Reply Last reply 21 Mar 2024, 21:14
                  2
                  • C Chris Kawa
                    21 Mar 2024, 19:58

                    What is the difference/relationship between return result of event() and setting/clearing accepted, please?

                    Return value says whether your handler handled the event i.e. if you return false the filter will go to the next guy in the chain. If you return true it stops with you.

                    accept sets a property of the event itself - so anyone getting the pointer can check whether it was accepted.

                    While usually they're set symmetrically you could also reject the event and return true, meaning the event should be ignored and no one else should look at it or you could call accept and return false, meaning you consider the event handled by you, but if anyone else in the chain wants a stab at it they can.

                    Will do for Key_Enter. Is that the key on my numeric pad which I have never used once in my life?

                    Yup, that's the one :)

                    J Online
                    J Online
                    JonB
                    wrote on 21 Mar 2024, 21:14 last edited by
                    #14

                    @Chris-Kawa
                    Thanks, interesting.

                    Take my case. Clearly the vital thing is the return result (I don't want anyone else/the shortcut handler to deal with it), which I have right. Let's say I fail to accept(). What difference could that make? Nobody else could look at it? Does that matter?

                    If Key_Enter is the unknown key on the right, I certainly don't want my line edit contaminated by bothering to handle it. Undefined behaviour is fine. I'm actually happy to leave that as a shortcut if it's wanted.

                    C 1 Reply Last reply 22 Mar 2024, 00:26
                    0
                    • J JonB
                      21 Mar 2024, 21:14

                      @Chris-Kawa
                      Thanks, interesting.

                      Take my case. Clearly the vital thing is the return result (I don't want anyone else/the shortcut handler to deal with it), which I have right. Let's say I fail to accept(). What difference could that make? Nobody else could look at it? Does that matter?

                      If Key_Enter is the unknown key on the right, I certainly don't want my line edit contaminated by bothering to handle it. Undefined behaviour is fine. I'm actually happy to leave that as a shortcut if it's wanted.

                      C Online
                      C Online
                      Chris Kawa
                      Lifetime Qt Champion
                      wrote on 22 Mar 2024, 00:26 last edited by Chris Kawa
                      #15

                      Let's say I fail to accept(). What difference could that make? Nobody else could look at it? Does that matter?

                      If you don't accept and return true it basically means "I've handled this event by deciding it doesn't matter". Keep in mind that this refers to the ShortcutOverride event, not the key press, so in other words it's "I've handled the event by ensuring nobody is overriding the shortcut. Let it eat the key".

                      That's how it works for this particular case. Not all events are made equal though. Some of them are more of a notification than a question, like when the OS informs you a color scheme has changed. You can't really meaningfully reject those events, as they are just informing you that something already happened, so nobody is looking at whether you accept those or not.
                      The return value is part of the event propagation mechanism to figure out when to stop propagating. The accepted/rejected bool is sort of a payload of the event that tells the sender at the end of propagation whether you did something with the event or not. That information is not always interesting to the sender, so some check it and some don't.

                      If Key_Enter is the unknown key on the right, I certainly don't want my line edit contaminated by bothering to handle it

                      It already does handle it. There are two keys that do the same thing on the QLineEdit, but you only defended against shortcut shadowing one of them. I just suggested to defend them both for consistency, but it's of course up to you which user habits you support.

                      Personally I use Enter all the time. It's just closer than Return when I have my hand on a mouse to the right, so I can just reach out with a thumb :)

                      J 1 Reply Last reply 22 Mar 2024, 08:15
                      1
                      • C Chris Kawa
                        22 Mar 2024, 00:26

                        Let's say I fail to accept(). What difference could that make? Nobody else could look at it? Does that matter?

                        If you don't accept and return true it basically means "I've handled this event by deciding it doesn't matter". Keep in mind that this refers to the ShortcutOverride event, not the key press, so in other words it's "I've handled the event by ensuring nobody is overriding the shortcut. Let it eat the key".

                        That's how it works for this particular case. Not all events are made equal though. Some of them are more of a notification than a question, like when the OS informs you a color scheme has changed. You can't really meaningfully reject those events, as they are just informing you that something already happened, so nobody is looking at whether you accept those or not.
                        The return value is part of the event propagation mechanism to figure out when to stop propagating. The accepted/rejected bool is sort of a payload of the event that tells the sender at the end of propagation whether you did something with the event or not. That information is not always interesting to the sender, so some check it and some don't.

                        If Key_Enter is the unknown key on the right, I certainly don't want my line edit contaminated by bothering to handle it

                        It already does handle it. There are two keys that do the same thing on the QLineEdit, but you only defended against shortcut shadowing one of them. I just suggested to defend them both for consistency, but it's of course up to you which user habits you support.

                        Personally I use Enter all the time. It's just closer than Return when I have my hand on a mouse to the right, so I can just reach out with a thumb :)

                        J Online
                        J Online
                        JonB
                        wrote on 22 Mar 2024, 08:15 last edited by
                        #16

                        @Chris-Kawa
                        Thanks. Sorry to press, but I'm interested and still don't quite get the effect. Obviously I understand here I will accept as well as return true. But can you give an example (not code just explanation) of any event override where returning true but failing to accept causes some different behaviour upstream (or do I mean downstream?) behaviour from if it had also accepted it? A tangible example where behaviour would differ.

                        I have the mouse maybe 10 inches from the edge of the keyboard. My thumb is not that long! I have never used the numeric keypad or the Enter key ever on any keyboard. Frankly I suspect they are devil's spawn, there to tempt the unwary into unnecessary wickedness and gluttony.

                        C 1 Reply Last reply 22 Mar 2024, 21:07
                        0
                        • J JonB referenced this topic on 22 Mar 2024, 13:09
                        • J JonB
                          22 Mar 2024, 08:15

                          @Chris-Kawa
                          Thanks. Sorry to press, but I'm interested and still don't quite get the effect. Obviously I understand here I will accept as well as return true. But can you give an example (not code just explanation) of any event override where returning true but failing to accept causes some different behaviour upstream (or do I mean downstream?) behaviour from if it had also accepted it? A tangible example where behaviour would differ.

                          I have the mouse maybe 10 inches from the edge of the keyboard. My thumb is not that long! I have never used the numeric keypad or the Enter key ever on any keyboard. Frankly I suspect they are devil's spawn, there to tempt the unwary into unnecessary wickedness and gluttony.

                          C Online
                          C Online
                          Chris Kawa
                          Lifetime Qt Champion
                          wrote on 22 Mar 2024, 21:07 last edited by
                          #17

                          can you give an example (not code just explanation) of any event override where returning true but failing to accept causes some different behaviour

                          A very common example is the close event. If you accept() it the window will close. If you ignore() it the window will stay open.

                          Frankly I suspect they are devil's spawn, there to tempt the unwary into unnecessary wickedness and gluttony.

                          All true. Those who had congress with the beast tend to develop elongated fingers turning into claws further down the line, letting them reach the notoriously elusive and distant Enter key with more ease.

                          J 1 Reply Last reply 23 Mar 2024, 09:54
                          1
                          • C Chris Kawa
                            22 Mar 2024, 21:07

                            can you give an example (not code just explanation) of any event override where returning true but failing to accept causes some different behaviour

                            A very common example is the close event. If you accept() it the window will close. If you ignore() it the window will stay open.

                            Frankly I suspect they are devil's spawn, there to tempt the unwary into unnecessary wickedness and gluttony.

                            All true. Those who had congress with the beast tend to develop elongated fingers turning into claws further down the line, letting them reach the notoriously elusive and distant Enter key with more ease.

                            J Online
                            J Online
                            JonB
                            wrote on 23 Mar 2024, 09:54 last edited by
                            #18

                            @Chris-Kawa
                            I'm not going to lie, I still don't fully understand the behaviour/consequences for event->accept() or not! However, I discovered that the code I had without it did not always work correctly (sometimes it did, sometimes not when it hit my return true but still it treated it as a shortcut). I put in e->accept() and now it works consistently, and so I have corrected my solution code to include it.

                            C 1 Reply Last reply 23 Mar 2024, 12:01
                            0
                            • J JonB
                              23 Mar 2024, 09:54

                              @Chris-Kawa
                              I'm not going to lie, I still don't fully understand the behaviour/consequences for event->accept() or not! However, I discovered that the code I had without it did not always work correctly (sometimes it did, sometimes not when it hit my return true but still it treated it as a shortcut). I put in e->accept() and now it works consistently, and so I have corrected my solution code to include it.

                              C Online
                              C Online
                              Chris Kawa
                              Lifetime Qt Champion
                              wrote on 23 Mar 2024, 12:01 last edited by Chris Kawa
                              #19

                              @JonB Maybe this example will help. Say you have a hierarchy of widgets like this:
                              Window -> TabWidget -> Groupbox -> TextEdit

                              When you send some event to the TextEdit the sequence in pseudo code is like this:

                              QWidget* widget = TextEdit;
                              QEvent* event = ...
                              
                              while(widget && !widget->event(event))
                              {
                                  widget = widget->parentWidget();
                              }
                              
                              bool result = event->isAccepted();
                              doSomethingWithResult(result);
                              
                              

                              i.e. it goes up the parent tree until one of the widgets returns true and then it checks whether the event was accepted or not and does something with it.

                              If you return true but don't either accept or ignore the event it will be left in whatever state the previous handler on the stack left it with. If you're the only one or none of the handlers touched it it's gonna be whatever the event sender initialized it with and that differs depending on event - some are accepted by default and some are ignored by default.

                              J 1 Reply Last reply 23 Mar 2024, 12:12
                              3
                              • C Chris Kawa
                                23 Mar 2024, 12:01

                                @JonB Maybe this example will help. Say you have a hierarchy of widgets like this:
                                Window -> TabWidget -> Groupbox -> TextEdit

                                When you send some event to the TextEdit the sequence in pseudo code is like this:

                                QWidget* widget = TextEdit;
                                QEvent* event = ...
                                
                                while(widget && !widget->event(event))
                                {
                                    widget = widget->parentWidget();
                                }
                                
                                bool result = event->isAccepted();
                                doSomethingWithResult(result);
                                
                                

                                i.e. it goes up the parent tree until one of the widgets returns true and then it checks whether the event was accepted or not and does something with it.

                                If you return true but don't either accept or ignore the event it will be left in whatever state the previous handler on the stack left it with. If you're the only one or none of the handlers touched it it's gonna be whatever the event sender initialized it with and that differs depending on event - some are accepted by default and some are ignored by default.

                                J Online
                                J Online
                                JonB
                                wrote on 23 Mar 2024, 12:12 last edited by JonB
                                #20

                                @Chris-Kawa
                                6 lines of code are worth a thousand words ;) Perfectly clear now!

                                1 Reply Last reply
                                0
                                • J JonB referenced this topic on 25 Mar 2024, 08:20

                                15/20

                                22 Mar 2024, 00:26

                                • Login

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