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. Passing QWheelEvents to child causes infinite loop
Forum Updated to NodeBB v4.3 + New Features

Passing QWheelEvents to child causes infinite loop

Scheduled Pinned Locked Moved Unsolved General and Desktop
6 Posts 4 Posters 502 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.
  • PhabSealsP Offline
    PhabSealsP Offline
    PhabSeals
    wrote on last edited by
    #1

    I have a container QWidget which can contain another input widget (combobox, slider, spinbox, etc) which is receiving QWheelEvents and it needs to pass these QWheelEvents on to the child widget to interpret (i.e. to change the value in the spinbox). I have done this by overriding QWidget::wheelEvent(QWheelEvent* event).

    void MyWidget::wheelEvent(QWheelEvent* event)
    {
        QApplication::sendEvent(childWidget, event);
    }
    

    However, if for some reason the child widget cannot accept the wheel event (such as it is disabled) the QWheelEvent is passed back to the parent object creating an infinite loop.

    The original QWheelEvent is being synthesized from an event filter in the QApplication and sent using

    //Using Qt 5.6.3
    QWheelEvent wheelEvent = QWheelEvent(widgetInFocus->pos(),
                                         widgetInFocus->mapToGlobal(widgetInFocus->pos()),
                                         QPoint(0,0),
                                         QPoint(0,120),
                                         120,
                                         Qt::Vertical,
                                         Qt::NoButton,
                                         Qt::NoModifier,
                                         Qt::ScrollEnd,
                                         Qt::MouseEventSynthesizedByApplication);
    
    QApplication::sendEvent(widgetInFocus, wheelEvent)
    

    I also can't send the wheelEvent directly to the child object because there is no way of accessing it in the QApplication event filter because the QApplication does not know if widgetInFocus is a MyWidget object or not.

    Is there a way I can prevent this infinite loop?

    jeremy_kJ 1 Reply Last reply
    0
    • Christian EhrlicherC Online
      Christian EhrlicherC Online
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Apart from the question why a subwidget should get such an event when it doesn't have the focus - simply remember the event in MyWidget::event() and when it's coming again don't call sendEvent()

      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
      Visit the Qt Academy at https://academy.qt.io/catalog

      1 Reply Last reply
      2
      • PhabSealsP Offline
        PhabSealsP Offline
        PhabSeals
        wrote on last edited by PhabSeals
        #3

        So I tried comparing the event pointer to the last received event pointer and they are always the same pointer address. So I can't ignore the event if it is the same as the previous.

        1 Reply Last reply
        0
        • Christian EhrlicherC Online
          Christian EhrlicherC Online
          Christian Ehrlicher
          Lifetime Qt Champion
          wrote on last edited by
          #4

          Then create a copy, send this and remember this pointer.

          Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
          Visit the Qt Academy at https://academy.qt.io/catalog

          1 Reply Last reply
          0
          • JoeCFDJ Offline
            JoeCFDJ Offline
            JoeCFD
            wrote on last edited by JoeCFD
            #5

            @PhabSeals said in Passing QWheelEvents to child causes infinite loop:

            wheelEvent(QWheelEvent* event)

            if wheelEvent(QWheelEvent* event) is not overridden in the child class of MyWidget, QApplication::sendEvent(widgetInFocus, wheelEvent) basically will call void MyWidget::wheelEvent(QWheelEvent* event) again and this is an infinite loop.

            Also you need to check at least
            if ( MyWidget pointer( or this) != widgetInFocus ) {
            QApplication::sendEvent(widgetInFocus, wheelEvent)
            }
            if MyWidget pointer(or this) is in focus, your code is also doomed. This can happen often on touch screen while the focus widget is not the one you expect.

            1 Reply Last reply
            0
            • PhabSealsP PhabSeals

              I have a container QWidget which can contain another input widget (combobox, slider, spinbox, etc) which is receiving QWheelEvents and it needs to pass these QWheelEvents on to the child widget to interpret (i.e. to change the value in the spinbox). I have done this by overriding QWidget::wheelEvent(QWheelEvent* event).

              void MyWidget::wheelEvent(QWheelEvent* event)
              {
                  QApplication::sendEvent(childWidget, event);
              }
              

              However, if for some reason the child widget cannot accept the wheel event (such as it is disabled) the QWheelEvent is passed back to the parent object creating an infinite loop.

              The original QWheelEvent is being synthesized from an event filter in the QApplication and sent using

              //Using Qt 5.6.3
              QWheelEvent wheelEvent = QWheelEvent(widgetInFocus->pos(),
                                                   widgetInFocus->mapToGlobal(widgetInFocus->pos()),
                                                   QPoint(0,0),
                                                   QPoint(0,120),
                                                   120,
                                                   Qt::Vertical,
                                                   Qt::NoButton,
                                                   Qt::NoModifier,
                                                   Qt::ScrollEnd,
                                                   Qt::MouseEventSynthesizedByApplication);
              
              QApplication::sendEvent(widgetInFocus, wheelEvent)
              

              I also can't send the wheelEvent directly to the child object because there is no way of accessing it in the QApplication event filter because the QApplication does not know if widgetInFocus is a MyWidget object or not.

              Is there a way I can prevent this infinite loop?

              jeremy_kJ Offline
              jeremy_kJ Offline
              jeremy_k
              wrote on last edited by
              #6

              @PhabSeals said in Passing QWheelEvents to child causes infinite loop:

              I also can't send the wheelEvent directly to the child object because there is no way of accessing it in the QApplication event filter because the QApplication does not know if widgetInFocus is a MyWidget object or not.

              Presuming that MyWidget is registered with the metaobject system, ie uses Q_OBJECT, either of the following will resolve this question:

               !strcmp(widgetInFocus->staticMetaObject().className(), "MyWidget");
              
              qobject_cast<MyWidget *>(widgetInFocus) != nullptr;
              

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

              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