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. Proper event-handling in void event(QEvent *)
Forum Updated to NodeBB v4.3 + New Features

Proper event-handling in void event(QEvent *)

Scheduled Pinned Locked Moved Unsolved General and Desktop
12 Posts 4 Posters 1.2k 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.
  • A Axel Spoerl
    2 Aug 2023, 17:32

    @unzu
    What exactly is the expected behavior?
    If the custom push button is the ultimate and only consumer of gesture events, they should be accepted and trueshould be returned to indicate that the event has been consumed.
    The elsebranch becomes obselete, if the method returns within the if.

    U Offline
    U Offline
    unzu
    wrote on 2 Aug 2023, 18:44 last edited by
    #3

    @Axel-Spoerl
    I placed the call to the event-function of the base class into the else branch to process all paint/focus/etc events, while still being able to test the effects of returning true/false in case of the touch/button-press events.

    I noticed no difference, no matter if I returned true or false in the main branch. That's why I was wondering what results the return value leads to.

    Well, I am wondering why I receive the gesture-started event twice in my button.
    The first touch press (my finger stays on the button) results in two events being processed by the button event function.
    I think its actually the same event being processed twice. The event-state is both times GestureStarted.

    Greetings.

    A 1 Reply Last reply 3 Aug 2023, 05:21
    0
    • U unzu
      2 Aug 2023, 18:44

      @Axel-Spoerl
      I placed the call to the event-function of the base class into the else branch to process all paint/focus/etc events, while still being able to test the effects of returning true/false in case of the touch/button-press events.

      I noticed no difference, no matter if I returned true or false in the main branch. That's why I was wondering what results the return value leads to.

      Well, I am wondering why I receive the gesture-started event twice in my button.
      The first touch press (my finger stays on the button) results in two events being processed by the button event function.
      I think its actually the same event being processed twice. The event-state is both times GestureStarted.

      Greetings.

      A Offline
      A Offline
      Axel Spoerl
      Moderators
      wrote on 3 Aug 2023, 05:21 last edited by
      #4

      @unzu said in Proper event-handling in void event(QEvent *):

      I noticed no difference, no matter if I returned true or false in the main branch. That's why I was wondering what results the return value leads to.

      That’s probably because the button has no children to which the event could be delivered if false is returned.

      Well, I am wondering why I receive the gesture-started event twice in my button.
      The first touch press (my finger stays on the button) results in two events being processed by the button event function.
      I think its actually the same event being processed twice. The event-state is both times GestureStarted.

      Can you post the debug output?
      Do both events point to the same memory address?

      Software Engineer
      The Qt Company, Oslo

      1 Reply Last reply
      0
      • U unzu
        2 Aug 2023, 12:56

        Hello everyone,

        I've got a few questions about handling events in my own classes.

        Right now there are two dummy classes, PushButton and GroupBox which both inherit from their Qt counterparts, QPushButton and QGroupBox.

        I have implemented bool event(QEvent*) for testing purposes in both classes:

        bool PushButton::event(QEvent *event)
            {
                if (auto mouseEvent = dynamic_cast<QMouseEvent *>(event))
                {
                    qDebug() << "PushButton" << mouseEvent;
                    //mouseEvent->ignore();
                    //mouseEvent->accept();
                }
                else
                    return QPushButton::event(event);
            }
        

        My widget has a custom GroupBox inside of it and a custom PushButton is placed in the GroupBox.

        Somewhere in the documentation I've read that the events are by default accepted in most cases:
        Pressing the button produces the debug output for the button.
        Pressing the groupbox produces the debug output for the groupbox.

        Uncommenting the mouseEvent ->ignore() propagets the event to the parent.
        Pressing the button produces both the debug output for the button and the groupbox.
        So far so good. By using accept() and ignore() I can control the event propagation.

        What about the return value?
        The documentation says:

        bool QObject::event(QEvent *e)
        This virtual function receives events to an object and should return true if the event e was recognized and processed.

        I've tried returning both true and false and could not see any differences.

        In addition to that, I have changed the event(QEvent *) function to process QTapGesture in both classes :

                if (auto touchEvent = dynamic_cast<QGestureEvent *>(event))
                {
                    qDebug() << "GroupBox" << touchEvent;
                    //touchEvent->ignore();
                    //touchEvent->accept();
                }
                else
                    return QPushButton::event(event);
        

        Touching only the GroupBox gives the expected result: A single QTapGesture(GestureStarted) GroupBox output.

        However, touching the PushButton now produces three outputs:
        1 - The initial button output.
        2 - The output of the GroupBox.
        3 - Another button output.

        Even when accept()-ing the event, I still get two outputs:
        1 - The initial button output.
        2 - Another button output.

        Any hints on what is going on there?

        Thanks for your time and efforts!
        Unzu

        J Offline
        J Offline
        jeremy_k
        wrote on 3 Aug 2023, 15:39 last edited by
        #5

        @unzu said in Proper event-handling in void event(QEvent *):

        bool PushButton::event(QEvent *event)
            {
                if (auto mouseEvent = dynamic_cast<QMouseEvent *>(event))
                {
                    qDebug() << "PushButton" << mouseEvent;
                    //mouseEvent->ignore();
                    //mouseEvent->accept();
                }
                else
                    return QPushButton::event(event);
            }
        

        Skipping everything else in the thread, there are 2 significant errors in this code:

        1. The if branch contains no return statement, and there is no return statement after the if/else block. I believe this results in undefined behavior, but may be mistaken.

        2. Qt traditionally has not required RTTI. dynamic_cast<> may not work. Use QEvent::type() as demonstrated in the example, and static_cast<> if the event object itself is needed.

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

        J U 2 Replies Last reply 3 Aug 2023, 16:12
        2
        • J jeremy_k
          3 Aug 2023, 15:39

          @unzu said in Proper event-handling in void event(QEvent *):

          bool PushButton::event(QEvent *event)
              {
                  if (auto mouseEvent = dynamic_cast<QMouseEvent *>(event))
                  {
                      qDebug() << "PushButton" << mouseEvent;
                      //mouseEvent->ignore();
                      //mouseEvent->accept();
                  }
                  else
                      return QPushButton::event(event);
              }
          

          Skipping everything else in the thread, there are 2 significant errors in this code:

          1. The if branch contains no return statement, and there is no return statement after the if/else block. I believe this results in undefined behavior, but may be mistaken.

          2. Qt traditionally has not required RTTI. dynamic_cast<> may not work. Use QEvent::type() as demonstrated in the example, and static_cast<> if the event object itself is needed.

          J Offline
          J Offline
          JonB
          wrote on 3 Aug 2023, 16:12 last edited by
          #6

          @jeremy_k said in Proper event-handling in void event(QEvent *):

          The if branch contains no return statement, and there is no return statement after the if/else block. I believe this results in undefined behavior, but may be mistaken.

          Indeed it's "undefined". I'm surprised it compiles without error or at least warning!

          J 1 Reply Last reply 3 Aug 2023, 18:42
          1
          • J JonB
            3 Aug 2023, 16:12

            @jeremy_k said in Proper event-handling in void event(QEvent *):

            The if branch contains no return statement, and there is no return statement after the if/else block. I believe this results in undefined behavior, but may be mistaken.

            Indeed it's "undefined". I'm surprised it compiles without error or at least warning!

            J Offline
            J Offline
            jeremy_k
            wrote on 3 Aug 2023, 18:42 last edited by
            #7

            @JonB said in Proper event-handling in void event(QEvent *):

            @jeremy_k said in Proper event-handling in void event(QEvent *):

            The if branch contains no return statement, and there is no return statement after the if/else block. I believe this results in undefined behavior, but may be mistaken.

            Indeed it's "undefined". I'm surprised it compiles without error or at least warning!

            The diagnostic might be optional. gcc 12.1 reports:

            warning: control reaches end of non-void function [-Wreturn-type]

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

            J 1 Reply Last reply 3 Aug 2023, 18:45
            2
            • J jeremy_k
              3 Aug 2023, 18:42

              @JonB said in Proper event-handling in void event(QEvent *):

              @jeremy_k said in Proper event-handling in void event(QEvent *):

              The if branch contains no return statement, and there is no return statement after the if/else block. I believe this results in undefined behavior, but may be mistaken.

              Indeed it's "undefined". I'm surprised it compiles without error or at least warning!

              The diagnostic might be optional. gcc 12.1 reports:

              warning: control reaches end of non-void function [-Wreturn-type]

              J Offline
              J Offline
              JonB
              wrote on 3 Aug 2023, 18:45 last edited by
              #8

              @jeremy_k I always have -Wall on :) Shame this just isn't an error in C++.

              1 Reply Last reply
              1
              • J Offline
                J Offline
                jeremy_k
                wrote on 3 Aug 2023, 19:24 last edited by
                #9

                Probably an inheritance from the C legacy.

                https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf
                Section 6.9.1.12:

                If the } that terminates a function is reached, and the value of the function call is used by
                the caller, the behavior is undefined

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

                1 Reply Last reply
                0
                • J jeremy_k
                  3 Aug 2023, 15:39

                  @unzu said in Proper event-handling in void event(QEvent *):

                  bool PushButton::event(QEvent *event)
                      {
                          if (auto mouseEvent = dynamic_cast<QMouseEvent *>(event))
                          {
                              qDebug() << "PushButton" << mouseEvent;
                              //mouseEvent->ignore();
                              //mouseEvent->accept();
                          }
                          else
                              return QPushButton::event(event);
                      }
                  

                  Skipping everything else in the thread, there are 2 significant errors in this code:

                  1. The if branch contains no return statement, and there is no return statement after the if/else block. I believe this results in undefined behavior, but may be mistaken.

                  2. Qt traditionally has not required RTTI. dynamic_cast<> may not work. Use QEvent::type() as demonstrated in the example, and static_cast<> if the event object itself is needed.

                  U Offline
                  U Offline
                  unzu
                  wrote on 3 Aug 2023, 19:56 last edited by unzu 8 Mar 2023, 20:02
                  #10

                  @jeremy_k said in Proper event-handling in void event(QEvent *):

                  The if branch contains no return statement, and there is no return statement after the if/else block. I believe this results in undefined behavior, but may be mistaken.

                  Hey, thanks for your hints.

                  I've tried to explain it already a few posts above: In my actual code there was a return statement in both branches of the if/else block.

                  I alternately tested the effects of returning true/false and accepting/ignoring and forgot to add it to my small code snipped. I should've edited it right away after @Axel-Spoerl mentioned it. I will leave it for now to preserve the context.

                  Regarding your other point, I think the dynamic_cast actually screwed it up:

                  "TopButton" is placed ontop/inside of "BottomButton" (added to the layout of BottomButton). Both are PushButtons. This code produces the following result:

                  bool PushButton::event(QEvent *event) {
                      if(auto gestureEvent = dynamic_cast<QGestureEvent*>(event)) {        
                          if(auto tapGesture = gestureEvent->gesture(Qt::TapGesture)) {
                              qDebug() << text() << tapGesture;
                              event->accept();
                              return true;
                          }  else {
                              qDebug() << text() << "Event was no Tap-Gesture." << gestureEvent;
                              event->accept();
                              return true;
                          }
                      }
                      return QPushButton::event(event);
                  }
                  
                  • "TopButton" QTapGesture(state=GestureStarted,hotSpot=703.5,224.5,position=17.5,11.5) QGestureEvent(GestureOverride, 0x2431ef25f0)
                  • "TopButton" QTapGesture(state=GestureStarted,hotSpot=703.5,224.5,position=17.5,11.5) QGestureEvent(Gesture, 0x2431ef25f0)
                  • "TopButton" QTapGesture(state=GestureUpdated,hotSpot=703.5,224.5,position=17.5,11.5) QGestureEvent(Gesture, 0x2431ef25f0)
                  • "TopButton" QTapGesture(state=GestureFinished,hotSpot=703.5,224.5,position=17.5,11.5) QGestureEvent(Gesture, 0x2431ef25f0)

                  Meanwhile, the edited version of the code shown below leads to:

                  bool PushButton::event(QEvent *event) {
                      if(event->type() == QEvent::Type::Gesture) {
                          auto gestureEvent = dynamic_cast<QGestureEvent*>(event);
                          if(auto tapGesture = gestureEvent->gesture(Qt::TapGesture)) {
                              qDebug() << text() << tapGesture << event;
                              event->accept();
                              return true;
                          } else {
                              qDebug() << text() << "Event was no Tap-Gesture." << gestureEvent;
                              event->accept();
                              return true;
                          }
                      }
                      return QPushButton::event(event);
                  }
                  
                  • "TopButton" QTapGesture(state=GestureStarted,hotSpot=753.5,222,position=67.5,9) QGestureEvent(Gesture, 0xb261be2430)
                  • "TopButton" QTapGesture(state=GestureUpdated,hotSpot=753.5,222,position=67.5,9) QGestureEvent(Gesture, 0xb261be2430)
                  • "TopButton" QTapGesture(state=GestureFinished,hotSpot=753.5,222,position=67.5,9) QGestureEvent(Gesture, 0xb261be2430)

                  So I guess its working properly? :)
                  Another question related to this topic:
                  I receive the event in state GestureStarted and i accept() it.
                  Moving my finger produces the GestureUpdate-events until I leave the button or withdraw my finger.
                  Am I supposed to accept() those updates aswell?

                  Thanks for all the answers!

                  Edit: Do you know why the coloring of my code extracts looks so messy?

                  A 1 Reply Last reply 4 Aug 2023, 06:52
                  0
                  • U unzu
                    3 Aug 2023, 19:56

                    @jeremy_k said in Proper event-handling in void event(QEvent *):

                    The if branch contains no return statement, and there is no return statement after the if/else block. I believe this results in undefined behavior, but may be mistaken.

                    Hey, thanks for your hints.

                    I've tried to explain it already a few posts above: In my actual code there was a return statement in both branches of the if/else block.

                    I alternately tested the effects of returning true/false and accepting/ignoring and forgot to add it to my small code snipped. I should've edited it right away after @Axel-Spoerl mentioned it. I will leave it for now to preserve the context.

                    Regarding your other point, I think the dynamic_cast actually screwed it up:

                    "TopButton" is placed ontop/inside of "BottomButton" (added to the layout of BottomButton). Both are PushButtons. This code produces the following result:

                    bool PushButton::event(QEvent *event) {
                        if(auto gestureEvent = dynamic_cast<QGestureEvent*>(event)) {        
                            if(auto tapGesture = gestureEvent->gesture(Qt::TapGesture)) {
                                qDebug() << text() << tapGesture;
                                event->accept();
                                return true;
                            }  else {
                                qDebug() << text() << "Event was no Tap-Gesture." << gestureEvent;
                                event->accept();
                                return true;
                            }
                        }
                        return QPushButton::event(event);
                    }
                    
                    • "TopButton" QTapGesture(state=GestureStarted,hotSpot=703.5,224.5,position=17.5,11.5) QGestureEvent(GestureOverride, 0x2431ef25f0)
                    • "TopButton" QTapGesture(state=GestureStarted,hotSpot=703.5,224.5,position=17.5,11.5) QGestureEvent(Gesture, 0x2431ef25f0)
                    • "TopButton" QTapGesture(state=GestureUpdated,hotSpot=703.5,224.5,position=17.5,11.5) QGestureEvent(Gesture, 0x2431ef25f0)
                    • "TopButton" QTapGesture(state=GestureFinished,hotSpot=703.5,224.5,position=17.5,11.5) QGestureEvent(Gesture, 0x2431ef25f0)

                    Meanwhile, the edited version of the code shown below leads to:

                    bool PushButton::event(QEvent *event) {
                        if(event->type() == QEvent::Type::Gesture) {
                            auto gestureEvent = dynamic_cast<QGestureEvent*>(event);
                            if(auto tapGesture = gestureEvent->gesture(Qt::TapGesture)) {
                                qDebug() << text() << tapGesture << event;
                                event->accept();
                                return true;
                            } else {
                                qDebug() << text() << "Event was no Tap-Gesture." << gestureEvent;
                                event->accept();
                                return true;
                            }
                        }
                        return QPushButton::event(event);
                    }
                    
                    • "TopButton" QTapGesture(state=GestureStarted,hotSpot=753.5,222,position=67.5,9) QGestureEvent(Gesture, 0xb261be2430)
                    • "TopButton" QTapGesture(state=GestureUpdated,hotSpot=753.5,222,position=67.5,9) QGestureEvent(Gesture, 0xb261be2430)
                    • "TopButton" QTapGesture(state=GestureFinished,hotSpot=753.5,222,position=67.5,9) QGestureEvent(Gesture, 0xb261be2430)

                    So I guess its working properly? :)
                    Another question related to this topic:
                    I receive the event in state GestureStarted and i accept() it.
                    Moving my finger produces the GestureUpdate-events until I leave the button or withdraw my finger.
                    Am I supposed to accept() those updates aswell?

                    Thanks for all the answers!

                    Edit: Do you know why the coloring of my code extracts looks so messy?

                    A Offline
                    A Offline
                    Axel Spoerl
                    Moderators
                    wrote on 4 Aug 2023, 06:52 last edited by
                    #11

                    @unzu said in Proper event-handling in void event(QEvent *):

                    Moving my finger produces the GestureUpdate-events until I leave the button or withdraw my finger.
                    Am I supposed to accept() those updates aswell?

                    That depends on the use case. If another QObjectshould do something reasonable with these events, it's better to ignore them. If the custom button is supposed to absorb the noise and make sure, nothing gets distracted - it's better to accept and return true(even if nothing is actually done).

                    Edit: Do you know why the coloring of my code extracts looks so messy?

                    Have seen that before. No clue where that comes from.

                    Software Engineer
                    The Qt Company, Oslo

                    U 1 Reply Last reply 4 Aug 2023, 08:45
                    0
                    • A Axel Spoerl
                      4 Aug 2023, 06:52

                      @unzu said in Proper event-handling in void event(QEvent *):

                      Moving my finger produces the GestureUpdate-events until I leave the button or withdraw my finger.
                      Am I supposed to accept() those updates aswell?

                      That depends on the use case. If another QObjectshould do something reasonable with these events, it's better to ignore them. If the custom button is supposed to absorb the noise and make sure, nothing gets distracted - it's better to accept and return true(even if nothing is actually done).

                      Edit: Do you know why the coloring of my code extracts looks so messy?

                      Have seen that before. No clue where that comes from.

                      U Offline
                      U Offline
                      unzu
                      wrote on 4 Aug 2023, 08:45 last edited by unzu 8 Apr 2023, 08:48
                      #12

                      @Axel-Spoerl said in Proper event-handling in void event(QEvent *):

                      That depends on the use case. If another QObjectshould do something reasonable with these events, it's better to ignore them. If the custom button is supposed to absorb the noise and make sure, nothing gets distracted - it's better to accept and return true(even if nothing is actually done).

                      Okay, will do that.
                      So far my touch-buttons are working mostly fine.

                      However there is still one annyoing thing:

                      If I place multiple of those buttons together in a groupbox, frame, etc., I can trigger multiple tap gestures at the same sime.

                      1. Pressing Button A
                        Button A "Gesture started"

                      2. Pressing Button B
                        Button B "Gesture started"

                      3. Withdrawing one finger from Button A/B
                        Button A/B "Gesture finished"

                      4. Withdrawing second finger from other Button B/A
                        Button B/A "Gesture finished"

                      This behaviour is fine for me: It is actually multi-touch support and does not hurt me.
                      However, if I accidentally touch the underlying QGroupBox, the event gets canceled:

                      1. Pressing Button A
                        Button A "Gesture started"

                      2. Touching the GroupBox with a second finger
                        Button A "Gesture canceled"

                      3. Withdrawing one finger of Button A or the GroupBox
                        Nothing happens.

                      4. Withdrawing the second finger
                        Nothing happens.

                      Is there a way to setup these events so that the behaviour is uniform:

                      1. Touching something other than the currently pressed Button always causes "Gesture canceled" in the Button (basically only single-touch support)
                      2. Touching something other than the currently pressed Button never causes "gesture canceled" (basically multi-touch support).

                      Thanks for your support!

                      1 Reply Last reply
                      0

                      12/12

                      4 Aug 2023, 08:45

                      • Login

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