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. QTabWidget in QScroll area : concurrent scrolling
Forum Updated to NodeBB v4.3 + New Features

QTabWidget in QScroll area : concurrent scrolling

Scheduled Pinned Locked Moved Solved General and Desktop
16 Posts 4 Posters 1.5k 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.
  • S Offline
    S Offline
    SuperSelrak
    wrote on last edited by SuperSelrak
    #1

    I have a QTabWidget some levels deeper in a QScrollArea. Built-in is the possibility to use the mouse scroll wheel to cycle through tabs.

    However, in my situation, this will also cause the QScrollArea to scroll up or down - so that now my mouse is not on the tab bar anymore and I have to move it (and also I have to look up or down to visually follow the tab bar)

    This is undesired. I would like the tab bar to completely consume the scroll event and hide it entirely from the scroll area, to allow smooth, continuous scrolling through my tabs. Is that possible ?

    Of note that I have other spin boxes and combo boxes that do show this behavior natively. I saw that they have the focus policy set to WheelFocus, which I now have set for my QTabWidget as well - to no avail.

    I have also set the focus policy of the tab bar of the QTabWidget (myTabWidget->tabBar()) to WheelFocus via a line of code, also to no avail.

    S mzimmersM 2 Replies Last reply
    0
    • Pl45m4P Pl45m4

      @SuperSelrak said in QTabWidget in QScroll area : concurrent scrolling:

      I can't easily subclass the QTabBar when using the designer, can I ?
      Using the designer, I do not have access to the QTabBar itself, rather only to the QTabWidget, which internally creates and sets its QTabBar.

      You wont make it very far in programming/Qt, when you only want to use QtDesigner :)
      It's an additional tool to create simple widgets/layouts "quick&easy". As soon as you need further logic or want to do custom stuff, QtDesigner cant help you anymore. Therefore it's recommended to learn how these things work, before using Designer :)

      On what would I apply the event filter ? Based on what ?

      You could install it on QTabWidget and check if the WheelEvent originates from TabBar or the tabBar is focused and then handle it.

      • https://doc.qt.io/qt-6/qwheelevent.html#details
      S Offline
      S Offline
      SuperSelrak
      wrote on last edited by
      #11

      @Pl45m4 I can definitely tell that the Qt Designer has its limitations, though I would disagree that it is weak.

      Still, I managed to reimplement QTabWidget::wheelEvent in that way :

      void wheelEvent(QWheelEvent * event) override
          {
              QWidget::wheelEvent(event);
              if(this->tabBar()->rect().contains(this->tabBar()->mapFromGlobal(event->globalPos())))
              {
                  event->accept();
              }
          };
      

      The call to QWidget's version of wheelEvent must come first if at all, because it calls QEvent ::ignore which clears the accept flag parameter of the event object. I could have also omitted it.

      And this does the job, both of limiting event capture to the tab bar while also retaining full use of the Designer (since I can now ask it to use this subclassed QTabWidget)

      I am not sure I understand what the Event Filter would do better. Would it stop the even from propagating upwards (which is what I need) ? Would I use similar code to figure if the tab bar is under the mouse ?

      What about "the tab bar is focused" ? Does it mean that I am sure that if the tab bar (which has WheelFocus policy) has focus at the time of the event, then it means that the mouse was over it as I scrolled ?

      Also, underMouse did not work for some reason. Any insights ? Would have looked nicer.

      Pl45m4P mzimmersM 2 Replies Last reply
      0
      • S SuperSelrak

        I have a QTabWidget some levels deeper in a QScrollArea. Built-in is the possibility to use the mouse scroll wheel to cycle through tabs.

        However, in my situation, this will also cause the QScrollArea to scroll up or down - so that now my mouse is not on the tab bar anymore and I have to move it (and also I have to look up or down to visually follow the tab bar)

        This is undesired. I would like the tab bar to completely consume the scroll event and hide it entirely from the scroll area, to allow smooth, continuous scrolling through my tabs. Is that possible ?

        Of note that I have other spin boxes and combo boxes that do show this behavior natively. I saw that they have the focus policy set to WheelFocus, which I now have set for my QTabWidget as well - to no avail.

        I have also set the focus policy of the tab bar of the QTabWidget (myTabWidget->tabBar()) to WheelFocus via a line of code, also to no avail.

        S Offline
        S Offline
        SuperSelrak
        wrote on last edited by
        #2
        This post is deleted!
        1 Reply Last reply
        0
        • S SuperSelrak

          I have a QTabWidget some levels deeper in a QScrollArea. Built-in is the possibility to use the mouse scroll wheel to cycle through tabs.

          However, in my situation, this will also cause the QScrollArea to scroll up or down - so that now my mouse is not on the tab bar anymore and I have to move it (and also I have to look up or down to visually follow the tab bar)

          This is undesired. I would like the tab bar to completely consume the scroll event and hide it entirely from the scroll area, to allow smooth, continuous scrolling through my tabs. Is that possible ?

          Of note that I have other spin boxes and combo boxes that do show this behavior natively. I saw that they have the focus policy set to WheelFocus, which I now have set for my QTabWidget as well - to no avail.

          I have also set the focus policy of the tab bar of the QTabWidget (myTabWidget->tabBar()) to WheelFocus via a line of code, also to no avail.

          mzimmersM Offline
          mzimmersM Offline
          mzimmers
          wrote on last edited by
          #3

          @SuperSelrak to what object are you applying the scroll bar?

          S 1 Reply Last reply
          0
          • mzimmersM mzimmers

            @SuperSelrak to what object are you applying the scroll bar?

            S Offline
            S Offline
            SuperSelrak
            wrote on last edited by SuperSelrak
            #4

            @mzimmers Thank you for your interest ! Not sure I understand the question though. The QScrollArea is a level of its own somewhere in the hierarchy. It s contained by a QWidget, and it contains (a few levels down) my QTabWidget where I want to scroll through tabs. The other widgets (combo box, spin box) where the scrolling works (i.e. applies with full focus to only that widget and not the scroll area) are at the same level as this QTabWidget.

            Does that answer the question ? What does "apply the scroll bar to" mean ?

            mzimmersM 1 Reply Last reply
            0
            • S SuperSelrak referenced this topic on
            • S SuperSelrak

              @mzimmers Thank you for your interest ! Not sure I understand the question though. The QScrollArea is a level of its own somewhere in the hierarchy. It s contained by a QWidget, and it contains (a few levels down) my QTabWidget where I want to scroll through tabs. The other widgets (combo box, spin box) where the scrolling works (i.e. applies with full focus to only that widget and not the scroll area) are at the same level as this QTabWidget.

              Does that answer the question ? What does "apply the scroll bar to" mean ?

              mzimmersM Offline
              mzimmersM Offline
              mzimmers
              wrote on last edited by
              #5

              @SuperSelrak sorry for my unfortunate choice of words; what I should have asked is, to which object are you applying QScrollArea::setWidget()? I'm not sure this is the problem, but it's worth looking at.

              Might not hurt to show a little of your code, too.

              S 1 Reply Last reply
              0
              • mzimmersM mzimmers

                @SuperSelrak sorry for my unfortunate choice of words; what I should have asked is, to which object are you applying QScrollArea::setWidget()? I'm not sure this is the problem, but it's worth looking at.

                Might not hurt to show a little of your code, too.

                S Offline
                S Offline
                SuperSelrak
                wrote on last edited by SuperSelrak
                #6

                @mzimmers Well okay, I actually use the Qt Designer, for better or for worse. But, it seems my QScrollArea comes with a widget called scrollAreaWidgetContents which is set as the scroll area's widget. (Sort of a standard thing in Qt AFAICT, similarly my tabs in my QTabWidgets have individual widgets called [...]Contents as the holder for anything under them)

                Here's everything I think is relevant to our cause from the auto-generated ui_[...] file :

                scrollArea = new QScrollArea(TrexDisplayClass);
                scrollArea->setObjectName(QString::fromUtf8("scrollArea"));
                scrollArea->setFocusPolicy(Qt::NoFocus);
                scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
                scrollArea->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents);
                scrollArea->setWidgetResizable(true);
                scrollAreaWidgetContents = new QWidget();
                scrollAreaWidgetContents->setObjectName(QString::fromUtf8("scrollAreaWidgetContents"));
                scrollAreaWidgetContents->setGeometry(QRect(0, 0, 653, 1272));
                tabNewSettings = new QWidget();
                tabNewSettings->setObjectName(QString::fromUtf8("tabNewSettings"));
                tabWidget = new QTabWidget(scrollAreaWidgetContents);
                tabWidget->setObjectName(QString::fromUtf8("tabWidget"));
                sizePolicy.setHeightForWidth(tabWidget->sizePolicy().hasHeightForWidth());
                tabWidget->setSizePolicy(sizePolicy);
                tabWidget->setFocusPolicy(Qt::TabFocus);
                
                m_gbDetailedProcessing = new QGroupBox(tabNewSettings);
                m_gbDetailedProcessing->setObjectName(QString::fromUtf8("m_gbDetailedProcessing"));
                m_gbDetailedProcessing->setCheckable(true);
                m_gbDetailedProcessing->setChecked(true);
                groupBox_3 = new QGroupBox(m_gbDetailedProcessing);
                groupBox_3->setObjectName(QString::fromUtf8("groupBox_3"));
                gridLayout_20 = new QGridLayout(groupBox_3);
                gridLayout_20->setObjectName(QString::fromUtf8("gridLayout_20"));
                
                tabWidgetDetailedStep = new QTabWidget(groupBox_3);
                tabWidgetDetailedStep->setObjectName(QString::fromUtf8("tabWidgetDetailedStep"));
                tabWidgetDetailedStep->setFocusPolicy(Qt::WheelFocus);
                tabWidgetDetailedStep->setDocumentMode(false);
                tabWidgetDetailedStepTab1 = new QWidget();
                tabWidgetDetailedStepTab1->setObjectName(QString::fromUtf8("tabWidgetDetailedStepTab1"));
                tabWidgetDetailedStep->addTab(tabWidgetDetailedStepTab1, QString());
                tabWidgetDetailedStepTab2 = new QWidget();
                tabWidgetDetailedStepTab2->setObjectName(QString::fromUtf8("tabWidgetDetailedStepTab2"));
                tabWidgetDetailedStep->addTab(tabWidgetDetailedStepTab2, QString());
                ... more tabs to tabWidgetDetailedStep
                
                gridLayout_20->addWidget(tabWidgetDetailedStep, 5, 1, 1, 1);
                tabWidget->addTab(tabNewSettings, QString());
                scrollArea->setWidget(scrollAreaWidgetContents);
                tabWidget->raise();
                

                Basically :
                tabWidgetDetailedStepTab(1|2)
                is in tabWidgetDetailedStep
                is in gridLayout_20 and also in groupbox_3
                is in m_gbDetailedProcessing
                is in tabNewSettings
                is a tab of tabWidget
                is in scrollAreaWidgetContents
                is the widget of scrollArea

                It is when scrolling between tabWidgetDetailedStepTab1 and tabWidgetDetailedStepTab2 that the scrollArea at the other end scrolls.

                Also I think that the way that QTabBar implements wheelEvent(QWheelEvent * event) is by (first of course changing tabs, as desired) and then calling QWidget::wheelEvent(event) which calls event->ignore() thus letting the event through to the parents, whereas for example QComboBox calls event->accept() thus consuming the event and not letting it be passed to parents, which I would venture to guess is why the behavior works for combo boxes and not for tab bars.

                This by looking at Qt5's source here :
                QTabBar
                QWidget
                QComboBox

                S 1 Reply Last reply
                0
                • S SuperSelrak

                  @mzimmers Well okay, I actually use the Qt Designer, for better or for worse. But, it seems my QScrollArea comes with a widget called scrollAreaWidgetContents which is set as the scroll area's widget. (Sort of a standard thing in Qt AFAICT, similarly my tabs in my QTabWidgets have individual widgets called [...]Contents as the holder for anything under them)

                  Here's everything I think is relevant to our cause from the auto-generated ui_[...] file :

                  scrollArea = new QScrollArea(TrexDisplayClass);
                  scrollArea->setObjectName(QString::fromUtf8("scrollArea"));
                  scrollArea->setFocusPolicy(Qt::NoFocus);
                  scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
                  scrollArea->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents);
                  scrollArea->setWidgetResizable(true);
                  scrollAreaWidgetContents = new QWidget();
                  scrollAreaWidgetContents->setObjectName(QString::fromUtf8("scrollAreaWidgetContents"));
                  scrollAreaWidgetContents->setGeometry(QRect(0, 0, 653, 1272));
                  tabNewSettings = new QWidget();
                  tabNewSettings->setObjectName(QString::fromUtf8("tabNewSettings"));
                  tabWidget = new QTabWidget(scrollAreaWidgetContents);
                  tabWidget->setObjectName(QString::fromUtf8("tabWidget"));
                  sizePolicy.setHeightForWidth(tabWidget->sizePolicy().hasHeightForWidth());
                  tabWidget->setSizePolicy(sizePolicy);
                  tabWidget->setFocusPolicy(Qt::TabFocus);
                  
                  m_gbDetailedProcessing = new QGroupBox(tabNewSettings);
                  m_gbDetailedProcessing->setObjectName(QString::fromUtf8("m_gbDetailedProcessing"));
                  m_gbDetailedProcessing->setCheckable(true);
                  m_gbDetailedProcessing->setChecked(true);
                  groupBox_3 = new QGroupBox(m_gbDetailedProcessing);
                  groupBox_3->setObjectName(QString::fromUtf8("groupBox_3"));
                  gridLayout_20 = new QGridLayout(groupBox_3);
                  gridLayout_20->setObjectName(QString::fromUtf8("gridLayout_20"));
                  
                  tabWidgetDetailedStep = new QTabWidget(groupBox_3);
                  tabWidgetDetailedStep->setObjectName(QString::fromUtf8("tabWidgetDetailedStep"));
                  tabWidgetDetailedStep->setFocusPolicy(Qt::WheelFocus);
                  tabWidgetDetailedStep->setDocumentMode(false);
                  tabWidgetDetailedStepTab1 = new QWidget();
                  tabWidgetDetailedStepTab1->setObjectName(QString::fromUtf8("tabWidgetDetailedStepTab1"));
                  tabWidgetDetailedStep->addTab(tabWidgetDetailedStepTab1, QString());
                  tabWidgetDetailedStepTab2 = new QWidget();
                  tabWidgetDetailedStepTab2->setObjectName(QString::fromUtf8("tabWidgetDetailedStepTab2"));
                  tabWidgetDetailedStep->addTab(tabWidgetDetailedStepTab2, QString());
                  ... more tabs to tabWidgetDetailedStep
                  
                  gridLayout_20->addWidget(tabWidgetDetailedStep, 5, 1, 1, 1);
                  tabWidget->addTab(tabNewSettings, QString());
                  scrollArea->setWidget(scrollAreaWidgetContents);
                  tabWidget->raise();
                  

                  Basically :
                  tabWidgetDetailedStepTab(1|2)
                  is in tabWidgetDetailedStep
                  is in gridLayout_20 and also in groupbox_3
                  is in m_gbDetailedProcessing
                  is in tabNewSettings
                  is a tab of tabWidget
                  is in scrollAreaWidgetContents
                  is the widget of scrollArea

                  It is when scrolling between tabWidgetDetailedStepTab1 and tabWidgetDetailedStepTab2 that the scrollArea at the other end scrolls.

                  Also I think that the way that QTabBar implements wheelEvent(QWheelEvent * event) is by (first of course changing tabs, as desired) and then calling QWidget::wheelEvent(event) which calls event->ignore() thus letting the event through to the parents, whereas for example QComboBox calls event->accept() thus consuming the event and not letting it be passed to parents, which I would venture to guess is why the behavior works for combo boxes and not for tab bars.

                  This by looking at Qt5's source here :
                  QTabBar
                  QWidget
                  QComboBox

                  S Offline
                  S Offline
                  SuperSelrak
                  wrote on last edited by
                  #7

                  @SuperSelrak Yes, I have subclassed QTabWidget reimplementing wheelEvent to forcefully accept the event and asked Qt Designer to replace the QTabWidget with this subclass. It does, and it works . scrolling on the QTabWidget now scrolls tabs only, not the QScrollArea. However that means that when I scroll anywhere on the QTabWidget then the even is consumed. But I want this to happen only on the tab bar. So I need to think about it further.

                  Pl45m4P 1 Reply Last reply
                  0
                  • S SuperSelrak

                    @SuperSelrak Yes, I have subclassed QTabWidget reimplementing wheelEvent to forcefully accept the event and asked Qt Designer to replace the QTabWidget with this subclass. It does, and it works . scrolling on the QTabWidget now scrolls tabs only, not the QScrollArea. However that means that when I scroll anywhere on the QTabWidget then the even is consumed. But I want this to happen only on the tab bar. So I need to think about it further.

                    Pl45m4P Offline
                    Pl45m4P Offline
                    Pl45m4
                    wrote on last edited by Pl45m4
                    #8

                    @SuperSelrak said in QTabWidget in QScroll area : concurrent scrolling:

                    Yes, I have subclassed QTabWidget reimplementing wheelEvent to forcefully accept the event and asked Qt Designer to replace the QTabWidget with this subclass

                    QTabBar is its own widget. What, if you accept the wheelEvent in a subclassed QTabBar class and set this custom tabBar to your QTabWidget?
                    Not tested, but then scrolling on places on the TabWidget other than the bar, might scroll the whole area again.

                    • https://doc.qt.io/qt-6/qtabbar.html#details
                    • https://doc.qt.io/qt-6/qtabwidget.html#setTabBar

                    Edit:

                    Using an eventFilter might be the better idea. The one above could work, but requires more code than needed, since the tabBar doesn't know about the logic/tabs to change. This is handled by the QTabWidget.
                    The eventfilter can check if the wheelevent's position is on tabBar, then consume it, otherwise don't.


                    If debugging is the process of removing software bugs, then programming must be the process of putting them in.

                    ~E. W. Dijkstra

                    S 1 Reply Last reply
                    0
                    • Pl45m4P Pl45m4

                      @SuperSelrak said in QTabWidget in QScroll area : concurrent scrolling:

                      Yes, I have subclassed QTabWidget reimplementing wheelEvent to forcefully accept the event and asked Qt Designer to replace the QTabWidget with this subclass

                      QTabBar is its own widget. What, if you accept the wheelEvent in a subclassed QTabBar class and set this custom tabBar to your QTabWidget?
                      Not tested, but then scrolling on places on the TabWidget other than the bar, might scroll the whole area again.

                      • https://doc.qt.io/qt-6/qtabbar.html#details
                      • https://doc.qt.io/qt-6/qtabwidget.html#setTabBar

                      Edit:

                      Using an eventFilter might be the better idea. The one above could work, but requires more code than needed, since the tabBar doesn't know about the logic/tabs to change. This is handled by the QTabWidget.
                      The eventfilter can check if the wheelevent's position is on tabBar, then consume it, otherwise don't.

                      S Offline
                      S Offline
                      SuperSelrak
                      wrote on last edited by SuperSelrak
                      #9

                      @Pl45m4 So yeah - but I can't easily subclass the QTabBar when using the designer, can I ?

                      Using the designer, I do not have access to the QTabBar itself, rather only to the QTabWidget, which internally creates and sets its QTabBar.

                      On what would I apply the event filter ? Based on what ? I was thinking about filtering events coming from the QTabBar at the level of the QTabWidget and accept only those (letting others through), but I don't know how to specify "comes from my own QTabBar".

                      Also the statement "the tabBar doesn't know about the logic/tabs to change" seems false to me for Qt 5.12.7 (I use 5.12.11) as per this code :

                      void QTabBar::wheelEvent(QWheelEvent *event)
                      {
                      #ifndef Q_OS_MAC
                          Q_D(QTabBar);
                          int offset = event->delta() > 0 ? -1 : 1;
                          d->setCurrentNextEnabledIndex(offset);
                          QWidget::wheelEvent(event);
                      #else
                          Q_UNUSED(event)
                      #endif
                      }
                      

                      @ code.qt.io

                      All I need is to add event->accept() here ! Very frustrating ! This seems to have been changed in Qt 6.3 by this commit - but the logic for switching tabs still seems to be in the QTabBar.

                      Pl45m4P 1 Reply Last reply
                      0
                      • S SuperSelrak

                        @Pl45m4 So yeah - but I can't easily subclass the QTabBar when using the designer, can I ?

                        Using the designer, I do not have access to the QTabBar itself, rather only to the QTabWidget, which internally creates and sets its QTabBar.

                        On what would I apply the event filter ? Based on what ? I was thinking about filtering events coming from the QTabBar at the level of the QTabWidget and accept only those (letting others through), but I don't know how to specify "comes from my own QTabBar".

                        Also the statement "the tabBar doesn't know about the logic/tabs to change" seems false to me for Qt 5.12.7 (I use 5.12.11) as per this code :

                        void QTabBar::wheelEvent(QWheelEvent *event)
                        {
                        #ifndef Q_OS_MAC
                            Q_D(QTabBar);
                            int offset = event->delta() > 0 ? -1 : 1;
                            d->setCurrentNextEnabledIndex(offset);
                            QWidget::wheelEvent(event);
                        #else
                            Q_UNUSED(event)
                        #endif
                        }
                        

                        @ code.qt.io

                        All I need is to add event->accept() here ! Very frustrating ! This seems to have been changed in Qt 6.3 by this commit - but the logic for switching tabs still seems to be in the QTabBar.

                        Pl45m4P Offline
                        Pl45m4P Offline
                        Pl45m4
                        wrote on last edited by
                        #10

                        @SuperSelrak said in QTabWidget in QScroll area : concurrent scrolling:

                        I can't easily subclass the QTabBar when using the designer, can I ?
                        Using the designer, I do not have access to the QTabBar itself, rather only to the QTabWidget, which internally creates and sets its QTabBar.

                        You wont make it very far in programming/Qt, when you only want to use QtDesigner :)
                        It's an additional tool to create simple widgets/layouts "quick&easy". As soon as you need further logic or want to do custom stuff, QtDesigner cant help you anymore. Therefore it's recommended to learn how these things work, before using Designer :)

                        On what would I apply the event filter ? Based on what ?

                        You could install it on QTabWidget and check if the WheelEvent originates from TabBar or the tabBar is focused and then handle it.

                        • https://doc.qt.io/qt-6/qwheelevent.html#details

                        If debugging is the process of removing software bugs, then programming must be the process of putting them in.

                        ~E. W. Dijkstra

                        S 1 Reply Last reply
                        0
                        • Pl45m4P Pl45m4

                          @SuperSelrak said in QTabWidget in QScroll area : concurrent scrolling:

                          I can't easily subclass the QTabBar when using the designer, can I ?
                          Using the designer, I do not have access to the QTabBar itself, rather only to the QTabWidget, which internally creates and sets its QTabBar.

                          You wont make it very far in programming/Qt, when you only want to use QtDesigner :)
                          It's an additional tool to create simple widgets/layouts "quick&easy". As soon as you need further logic or want to do custom stuff, QtDesigner cant help you anymore. Therefore it's recommended to learn how these things work, before using Designer :)

                          On what would I apply the event filter ? Based on what ?

                          You could install it on QTabWidget and check if the WheelEvent originates from TabBar or the tabBar is focused and then handle it.

                          • https://doc.qt.io/qt-6/qwheelevent.html#details
                          S Offline
                          S Offline
                          SuperSelrak
                          wrote on last edited by
                          #11

                          @Pl45m4 I can definitely tell that the Qt Designer has its limitations, though I would disagree that it is weak.

                          Still, I managed to reimplement QTabWidget::wheelEvent in that way :

                          void wheelEvent(QWheelEvent * event) override
                              {
                                  QWidget::wheelEvent(event);
                                  if(this->tabBar()->rect().contains(this->tabBar()->mapFromGlobal(event->globalPos())))
                                  {
                                      event->accept();
                                  }
                              };
                          

                          The call to QWidget's version of wheelEvent must come first if at all, because it calls QEvent ::ignore which clears the accept flag parameter of the event object. I could have also omitted it.

                          And this does the job, both of limiting event capture to the tab bar while also retaining full use of the Designer (since I can now ask it to use this subclassed QTabWidget)

                          I am not sure I understand what the Event Filter would do better. Would it stop the even from propagating upwards (which is what I need) ? Would I use similar code to figure if the tab bar is under the mouse ?

                          What about "the tab bar is focused" ? Does it mean that I am sure that if the tab bar (which has WheelFocus policy) has focus at the time of the event, then it means that the mouse was over it as I scrolled ?

                          Also, underMouse did not work for some reason. Any insights ? Would have looked nicer.

                          Pl45m4P mzimmersM 2 Replies Last reply
                          0
                          • S SuperSelrak

                            @Pl45m4 I can definitely tell that the Qt Designer has its limitations, though I would disagree that it is weak.

                            Still, I managed to reimplement QTabWidget::wheelEvent in that way :

                            void wheelEvent(QWheelEvent * event) override
                                {
                                    QWidget::wheelEvent(event);
                                    if(this->tabBar()->rect().contains(this->tabBar()->mapFromGlobal(event->globalPos())))
                                    {
                                        event->accept();
                                    }
                                };
                            

                            The call to QWidget's version of wheelEvent must come first if at all, because it calls QEvent ::ignore which clears the accept flag parameter of the event object. I could have also omitted it.

                            And this does the job, both of limiting event capture to the tab bar while also retaining full use of the Designer (since I can now ask it to use this subclassed QTabWidget)

                            I am not sure I understand what the Event Filter would do better. Would it stop the even from propagating upwards (which is what I need) ? Would I use similar code to figure if the tab bar is under the mouse ?

                            What about "the tab bar is focused" ? Does it mean that I am sure that if the tab bar (which has WheelFocus policy) has focus at the time of the event, then it means that the mouse was over it as I scrolled ?

                            Also, underMouse did not work for some reason. Any insights ? Would have looked nicer.

                            Pl45m4P Offline
                            Pl45m4P Offline
                            Pl45m4
                            wrote on last edited by
                            #12

                            @SuperSelrak said in QTabWidget in QScroll area : concurrent scrolling:

                            I would disagree that it is weak.

                            Depends on what you want to do. You will reach the limits as soon as you want to something else than the "out-of-the-box" behavior, which the standard widgets provide.
                            Also, it is annoying to check the XML ("ui") file or the Designer for options that may or may not got set and not show up in your code. Later nobody (or you) knows where this behavior is coming from :)

                            I am not sure I understand what the Event Filter would do better. Would it stop the even from propagating upwards (which is what I need) ?

                            As soon as the event is accepted, it stops the upwards propagation (most of the time).

                            • https://doc.qt.io/qt-6/qevent.html#accept

                            If debugging is the process of removing software bugs, then programming must be the process of putting them in.

                            ~E. W. Dijkstra

                            1 Reply Last reply
                            0
                            • S SuperSelrak

                              @Pl45m4 I can definitely tell that the Qt Designer has its limitations, though I would disagree that it is weak.

                              Still, I managed to reimplement QTabWidget::wheelEvent in that way :

                              void wheelEvent(QWheelEvent * event) override
                                  {
                                      QWidget::wheelEvent(event);
                                      if(this->tabBar()->rect().contains(this->tabBar()->mapFromGlobal(event->globalPos())))
                                      {
                                          event->accept();
                                      }
                                  };
                              

                              The call to QWidget's version of wheelEvent must come first if at all, because it calls QEvent ::ignore which clears the accept flag parameter of the event object. I could have also omitted it.

                              And this does the job, both of limiting event capture to the tab bar while also retaining full use of the Designer (since I can now ask it to use this subclassed QTabWidget)

                              I am not sure I understand what the Event Filter would do better. Would it stop the even from propagating upwards (which is what I need) ? Would I use similar code to figure if the tab bar is under the mouse ?

                              What about "the tab bar is focused" ? Does it mean that I am sure that if the tab bar (which has WheelFocus policy) has focus at the time of the event, then it means that the mouse was over it as I scrolled ?

                              Also, underMouse did not work for some reason. Any insights ? Would have looked nicer.

                              mzimmersM Offline
                              mzimmersM Offline
                              mzimmers
                              wrote on last edited by
                              #13

                              @SuperSelrak said in QTabWidget in QScroll area : concurrent scrolling:

                              The call to QWidget's version of wheelEvent must come first if at all,

                              I'm not sure I understand you, but I believe when you override a function, your overriding function will be called, first and only. The parent class's method isn't called.

                              JonBJ 1 Reply Last reply
                              0
                              • mzimmersM mzimmers

                                @SuperSelrak said in QTabWidget in QScroll area : concurrent scrolling:

                                The call to QWidget's version of wheelEvent must come first if at all,

                                I'm not sure I understand you, but I believe when you override a function, your overriding function will be called, first and only. The parent class's method isn't called.

                                JonBJ Online
                                JonBJ Online
                                JonB
                                wrote on last edited by JonB
                                #14

                                @mzimmers
                                @SuperSelrak is inserting an explicit call to the base/parent class's method being overridden, so that it does get called. Good practice, as it might do something needed. He explains why he puts this first (rather than, say, last) in his override.

                                mzimmersM S 2 Replies Last reply
                                2
                                • JonBJ JonB

                                  @mzimmers
                                  @SuperSelrak is inserting an explicit call to the base/parent class's method being overridden, so that it does get called. Good practice, as it might do something needed. He explains why he puts this first (rather than, say, last) in his override.

                                  mzimmersM Offline
                                  mzimmersM Offline
                                  mzimmers
                                  wrote on last edited by
                                  #15

                                  @JonB oh yes, of course...I do need to read more carefully. Sorry for the irrelevant post.

                                  1 Reply Last reply
                                  0
                                  • JonBJ JonB

                                    @mzimmers
                                    @SuperSelrak is inserting an explicit call to the base/parent class's method being overridden, so that it does get called. Good practice, as it might do something needed. He explains why he puts this first (rather than, say, last) in his override.

                                    S Offline
                                    S Offline
                                    SuperSelrak
                                    wrote on last edited by
                                    #16

                                    @JonB @mzimmers Yes, that was all in my thinking.

                                    @Pl45m4 Yes I understand. But as far as organizing widgets in a visually nice manner, nothing beats the designer in speed. Compiling every time I make the smallest change to test it just doesn't cut it ... and the "Use as placeholder for custom class" really can cover a lot, as I have discovered with this.

                                    Thanks all for contributions.

                                    1 Reply Last reply
                                    0
                                    • S SuperSelrak has marked this topic as solved on

                                    • Login

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