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. Set the horizontal scroll bar to be on the top of a widget instead of the bottom? (for the pages of a QTabWidget)
Forum Updated to NodeBB v4.3 + New Features

Set the horizontal scroll bar to be on the top of a widget instead of the bottom? (for the pages of a QTabWidget)

Scheduled Pinned Locked Moved Solved General and Desktop
9 Posts 2 Posters 1.9k 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.
  • mbruelM Offline
    mbruelM Offline
    mbruel
    wrote on last edited by
    #1

    Hi
    I guess this could seem a bit unusual but I've a problematic use case for my users.
    I'm having a QTabWidget on which I switched the tab position to the West.
    It looks something like this.
    alt text

    The page view can grow both horizontally and vertically.
    When it grows too much horizontally and if I've too many tabs, it's really uncomfortable to scroll the page horizontally: the user needs to first go down to the bottom (where he doesn't see anything on the page anymore) to be able to scroll horizontally...

    A simple solution would be to allow to have the scroll bar on the top of the page.
    Would this be possible in anyway? Or any suggestion for another solution?

    I'm not creating the scroll area. It's done by the QTabWidget. I'm just inserting pages using QTabWidget::insertTab

    PS: I forgot to say, the user can create as many Tabs as he wants...

    1 Reply Last reply
    0
    • mrjjM Offline
      mrjjM Offline
      mrjj
      Lifetime Qt Champion
      wrote on last edited by mrjj
      #2

      Hi
      Since there is a QScrolBar widget - i was wondering if you can just place on top in the layout and then connect the
      various signals to keep them in sync.
      Im not sure where the horizontal scrolls come from - as it looks like this with west tabs for me.

      alt text

      The biggest question is that if you can gain access to it or not.

      and then do something like (its 2 views here)
      connect(view1->horizontalScrollBar(), SIGNAL(valueChanged(int)), view2->horizontalScrollBar(), SLOT(setValue(int)));
      connect(view2->horizontalScrollBar(), SIGNAL(valueChanged(int)), view1->horizontalScrollBar(), SLOT(setValue(int)));
      with a standalone QScrollbar

      mbruelM 1 Reply Last reply
      0
      • mrjjM mrjj

        Hi
        Since there is a QScrolBar widget - i was wondering if you can just place on top in the layout and then connect the
        various signals to keep them in sync.
        Im not sure where the horizontal scrolls come from - as it looks like this with west tabs for me.

        alt text

        The biggest question is that if you can gain access to it or not.

        and then do something like (its 2 views here)
        connect(view1->horizontalScrollBar(), SIGNAL(valueChanged(int)), view2->horizontalScrollBar(), SLOT(setValue(int)));
        connect(view2->horizontalScrollBar(), SIGNAL(valueChanged(int)), view1->horizontalScrollBar(), SLOT(setValue(int)));
        with a standalone QScrollbar

        mbruelM Offline
        mbruelM Offline
        mbruel
        wrote on last edited by mbruel
        #3

        @mrjj
        hum that's could be a nice trick indeed!
        but yeah as you noticed, the issue is to get access to the scrollbar.
        it seems to be internal to the QTabWidget...

        Edit: here is a snapshot of the actual issue:
        alt text

        I've to go to the bottom of my Tabs to access the scrollbar of the page. I don't see anymore the headers of my table...
        And we can see that the scrollbar seems to be added by the QTabWidget... for all the pages...

        mrjjM 1 Reply Last reply
        0
        • mbruelM mbruel

          @mrjj
          hum that's could be a nice trick indeed!
          but yeah as you noticed, the issue is to get access to the scrollbar.
          it seems to be internal to the QTabWidget...

          Edit: here is a snapshot of the actual issue:
          alt text

          I've to go to the bottom of my Tabs to access the scrollbar of the page. I don't see anymore the headers of my table...
          And we can see that the scrollbar seems to be added by the QTabWidget... for all the pages...

          mrjjM Offline
          mrjjM Offline
          mrjj
          Lifetime Qt Champion
          wrote on last edited by mrjj
          #4

          @mbruel
          Hi
          I tried to look into it but i failed at making it show a horizontal scrollbar.
          You say you didnt add an extra scrollArea but i was not albe to get any horz scrollbars.
          Do you resize the actual Tab-Widget to get one ? ( the actual "tab" )

          When you have "the case", could you call
          table->dumpObjectTree();
          (it outputs to Application tab)

          and see if the scrollbar is listed ?

          If yes, we should be able to get hold of it by using FindChild.

          It might be created on the fly so that can be a gotcha as it often means it get deleted again.

          mbruelM 1 Reply Last reply
          1
          • mrjjM mrjj

            @mbruel
            Hi
            I tried to look into it but i failed at making it show a horizontal scrollbar.
            You say you didnt add an extra scrollArea but i was not albe to get any horz scrollbars.
            Do you resize the actual Tab-Widget to get one ? ( the actual "tab" )

            When you have "the case", could you call
            table->dumpObjectTree();
            (it outputs to Application tab)

            and see if the scrollbar is listed ?

            If yes, we should be able to get hold of it by using FindChild.

            It might be created on the fly so that can be a gotcha as it often means it get deleted again.

            mbruelM Offline
            mbruelM Offline
            mbruel
            wrote on last edited by
            #5

            @mrjj thanks for your help man :)

            Nice, I didn't know that dumpObjectTree... It can be quite useful!!
            Here is my dump.

            Debug: ReprocessingPlantPeriodWidget::  ((null):0, (null))
            Debug:     QStackedWidget::qt_tabwidget_stackedwidget  ((null):0, (null))
            Debug:         QWidget::  ((null):0, (null))
            Debug:         QStackedLayout::  ((null):0, (null))
            Debug:         DateValuesWidget::  ((null):0, (null))
            Debug:             QWidget::qt_scrollarea_viewport  ((null):0, (null))
            Debug:                 QComboBox::  ((null):0, (null))
            Debug:                     QStandardItemModel::  ((null):0, (null))
            Debug:                     QComboBoxPrivateContainer::  ((null):0, (null))
            Debug:                         QBoxLayout::  ((null):0, (null))
            Debug:                         QComboBoxListView::  ((null):0, (null))
            Debug:                             QWidget::qt_scrollarea_viewport  ((null):0, (null))
            Debug:                             QWidget::qt_scrollarea_hcontainer  ((null):0, (null))
            Debug:                                 QScrollBar::  ((null):0, (null))
            Debug:                                 QBoxLayout::  ((null):0, (null))
            Debug:                             QWidget::qt_scrollarea_vcontainer  ((null):0, (null))
            Debug:                                 QScrollBar::  ((null):0, (null))
            Debug:                                 QBoxLayout::  ((null):0, (null))
            Debug:                             QItemSelectionModel::  ((null):0, (null))
            Debug:                             QComboMenuDelegate::  ((null):0, (null))
            Debug:                         QComboBoxPrivateScroller::  ((null):0, (null))
            Debug:                         QComboBoxPrivateScroller::  ((null):0, (null))
            Debug:                 QPushButton::  ((null):0, (null))
            Debug:                 QPushButton::  ((null):0, (null))
            Debug:                 QComboBox::  ((null):0, (null))
            Debug:                     QStandardItemModel::  ((null):0, (null))
            Debug:                     QComboBoxPrivateContainer::  ((null):0, (null))
            Debug:                         QBoxLayout::  ((null):0, (null))
            Debug:                         QComboBoxListView::  ((null):0, (null))
            Debug:                             QWidget::qt_scrollarea_viewport  ((null):0, (null))
            Debug:                             QWidget::qt_scrollarea_hcontainer  ((null):0, (null))
            Debug:                                 QScrollBar::  ((null):0, (null))
            Debug:                                 QBoxLayout::  ((null):0, (null))
            Debug:                             QWidget::qt_scrollarea_vcontainer  ((null):0, (null))
            Debug:                                 QScrollBar::  ((null):0, (null))
            Debug:                                 QBoxLayout::  ((null):0, (null))
            Debug:                             QItemSelectionModel::  ((null):0, (null))
            Debug:                             QComboMenuDelegate::  ((null):0, (null))
            Debug:                         QComboBoxPrivateScroller::  ((null):0, (null))
            Debug:                         QComboBoxPrivateScroller::  ((null):0, (null))
            Debug:                 QWidget::  ((null):0, (null))
            Debug:                     QGridLayout::  ((null):0, (null))
            Debug:                     QPushButton::  ((null):0, (null))
            Debug:                 QComboBox::  ((null):0, (null))
            Debug:                     QStandardItemModel::  ((null):0, (null))
            Debug:                     QComboBoxPrivateContainer::  ((null):0, (null))
            Debug:                         QBoxLayout::  ((null):0, (null))
            Debug:                         QComboBoxListView::  ((null):0, (null))
            Debug:                             QWidget::qt_scrollarea_viewport  ((null):0, (null))
            Debug:                             QWidget::qt_scrollarea_hcontainer  ((null):0, (null))
            Debug:                                 QScrollBar::  ((null):0, (null))
            Debug:                                 QBoxLayout::  ((null):0, (null))
            Debug:                             QWidget::qt_scrollarea_vcontainer  ((null):0, (null))
            Debug:                                 QScrollBar::  ((null):0, (null))
            Debug:                                 QBoxLayout::  ((null):0, (null))
            Debug:                             QItemSelectionModel::  ((null):0, (null))
            Debug:                             QComboMenuDelegate::  ((null):0, (null))
            Debug:                         QComboBoxPrivateScroller::  ((null):0, (null))
            Debug:                         QComboBoxPrivateScroller::  ((null):0, (null))
            Debug:                 QWidget::  ((null):0, (null))
            Debug:                     QGridLayout::  ((null):0, (null))
            Debug:                     QPushButton::  ((null):0, (null))
            Debug:             QStyledItemDelegate::  ((null):0, (null))
            Debug:             QHeaderView::  ((null):0, (null))
            Debug:                 QWidget::qt_scrollarea_viewport  ((null):0, (null))
            Debug:                 QWidget::qt_scrollarea_hcontainer  ((null):0, (null))
            Debug:                     QScrollBar::  ((null):0, (null))
            Debug:                     QBoxLayout::  ((null):0, (null))
            Debug:                 QWidget::qt_scrollarea_vcontainer  ((null):0, (null))
            Debug:                     QScrollBar::  ((null):0, (null))
            Debug:                     QBoxLayout::  ((null):0, (null))
            Debug:                 QItemSelectionModel::  ((null):0, (null))
            Debug:             QHeaderView::  ((null):0, (null))
            Debug:                 QWidget::qt_scrollarea_viewport  ((null):0, (null))
            Debug:                 QWidget::qt_scrollarea_hcontainer  ((null):0, (null))
            Debug:                     QScrollBar::  ((null):0, (null))
            Debug:                     QBoxLayout::  ((null):0, (null))
            Debug:                 QWidget::qt_scrollarea_vcontainer  ((null):0, (null))
            Debug:                     QScrollBar::  ((null):0, (null))
            Debug:                     QBoxLayout::  ((null):0, (null))
            Debug:                 QItemSelectionModel::  ((null):0, (null))
            Debug:             QTableCornerButton::  ((null):0, (null))
            Debug:             QTableModel::  ((null):0, (null))
            Debug:             QItemSelectionModel::  ((null):0, (null))
            Debug:             QWidget::qt_scrollarea_vcontainer  ((null):0, (null))
            Debug:                 QScrollBar::  ((null):0, (null))
            Debug:                 QBoxLayout::  ((null):0, (null))
            Debug:             QWidget::qt_scrollarea_hcontainer  ((null):0, (null))
            Debug:                 QScrollBar::  ((null):0, (null))
            Debug:                 QBoxLayout::  ((null):0, (null))
            Debug:     QTabBar::qt_tabwidget_tabbar  ((null):0, (null))
            Debug:         GroupingsElemWidget::  ((null):0, (null))
            Debug:             QHBoxLayout::  ((null):0, (null))
            Debug:             QLabel::  ((null):0, (null))
            Debug:                 QWidgetTextControl::  ((null):0, (null))
            Debug:                     QTextDocument::  ((null):0, (null))
            Debug:                         QTextDocumentLayout::  ((null):0, (null))
            Debug:                             QTextImageHandler::  ((null):0, (null))
            Debug:                         QTextFrame::  ((null):0, (null))
            Debug:             QPushButton::  ((null):0, (null))
            Debug:         GroupingsAddWidget::  ((null):0, (null))
            Debug:             QComboBox::  ((null):0, (null))
            Debug:                 QStandardItemModel::  ((null):0, (null))
            Debug:                 QComboBoxPrivateContainer::  ((null):0, (null))
            Debug:                     QBoxLayout::  ((null):0, (null))
            Debug:                     QComboBoxListView::  ((null):0, (null))
            Debug:                         QWidget::qt_scrollarea_viewport  ((null):0, (null))
            Debug:                         QWidget::qt_scrollarea_hcontainer  ((null):0, (null))
            Debug:                             QScrollBar::  ((null):0, (null))
            Debug:                             QBoxLayout::  ((null):0, (null))
            Debug:                         QWidget::qt_scrollarea_vcontainer  ((null):0, (null))
            Debug:                             QScrollBar::  ((null):0, (null))
            Debug:                             QBoxLayout::  ((null):0, (null))
            Debug:                         QItemSelectionModel::  ((null):0, (null))
            Debug:                         QComboMenuDelegate::  ((null):0, (null))
            Debug:                     QComboBoxPrivateScroller::  ((null):0, (null))
            Debug:                     QComboBoxPrivateScroller::  ((null):0, (null))
            Debug:             QHBoxLayout::  ((null):0, (null))
            Debug:             QPushButton::  ((null):0, (null))
            Debug:         QLabel::  ((null):0, (null))
            Debug:             QWidgetTextControl::  ((null):0, (null))
            Debug:                 QTextDocument::  ((null):0, (null))
            Debug:                     QTextDocumentLayout::  ((null):0, (null))
            Debug:                         QTextImageHandler::  ((null):0, (null))
            Debug:                     QTextFrame::  ((null):0, (null))
            Debug:         QToolButton::  ((null):0, (null))
            Debug:         QToolButton::  ((null):0, (null))
            Debug:     QDoubleValidator::  ((null):0, (null))
            

            So it is my DateValuesWidget that is having the horizontal QScrollBar. I've just realised that it is not a simple QWidget but it inherits from QTableWidget so inderectly from QAbstractScrollArea. Thus the scrollbar is the one of my DateValuesWidget, not from the Page of the QTabWidget as I was thinking before. My bad...

            So good news, I can access the horizontal scrollbar and try your trick.
            Within my DateValuesWidget I'm able to hide it using setHorizontalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAlwaysOff);
            so I can access it using horizontalScrollBar()

            So what you're suggesting is that I instead of adding a DateValuesWidget (QTableWidget) in my page, I use a container QWidget that will have another scrollbar at the Top and the QTableWidget just under. This top scrollbar will be synched with the QTableWidget scrollbar. Am I right?

            Question: I don't want to see the top horizontal scrollbar when it is not needed (i.e: when QTableWidget doesn't have one). How can I test that the horizontal QScrollBar of a QAbstractScrollArea is visible or not?

            1 Reply Last reply
            0
            • mrjjM Offline
              mrjjM Offline
              mrjj
              Lifetime Qt Champion
              wrote on last edited by
              #6

              @mbruel said in Set the horizontal scroll bar to be on the top of a widget instead of the bottom? (for the pages of a QTabWidget):

              So what you're suggesting is that I instead of adding a DateValuesWidget (QTableWidget) in my page, I use a container QWidget that will have another scrollbar at the Top and the QTableWidget just under. This top scrollbar will be synched with the QTableWidget scrollbar. Am I right?

              Yes instead of single DateValuesWidget, then a container widget with a layout and then Scroll bar +
              DateValuesWidget under.

              • Question: I don't want to see the top horizontal scrollbar when it is not needed

              I wish it would have a signal but I dont think they added one :)
              poster here had same issue
              https://forum.qt.io/topic/84137/qscrollarea-signal-or-virtual-function-for-about-to-show-scrollbar
              I ended using rangeChanged to detect it.

              mbruelM 1 Reply Last reply
              2
              • mrjjM mrjj

                @mbruel said in Set the horizontal scroll bar to be on the top of a widget instead of the bottom? (for the pages of a QTabWidget):

                So what you're suggesting is that I instead of adding a DateValuesWidget (QTableWidget) in my page, I use a container QWidget that will have another scrollbar at the Top and the QTableWidget just under. This top scrollbar will be synched with the QTableWidget scrollbar. Am I right?

                Yes instead of single DateValuesWidget, then a container widget with a layout and then Scroll bar +
                DateValuesWidget under.

                • Question: I don't want to see the top horizontal scrollbar when it is not needed

                I wish it would have a signal but I dont think they added one :)
                poster here had same issue
                https://forum.qt.io/topic/84137/qscrollarea-signal-or-virtual-function-for-about-to-show-scrollbar
                I ended using rangeChanged to detect it.

                mbruelM Offline
                mbruelM Offline
                mbruel
                wrote on last edited by
                #7

                @mrjj great!
                I'm already trying it. I'm having this container QWidget with a Top scroll bar. I'm trying to do all the connections. I'll post the result when done or ask another question if I'm getting an issue.
                Cheers again!

                1 Reply Last reply
                1
                • mbruelM Offline
                  mbruelM Offline
                  mbruel
                  wrote on last edited by mbruel
                  #8

                  Nice, working like a charm \o/
                  @mrjj thanks again! I wouldn't thought we could solve this, that I may have to change the whole design...

                  Header:

                  class QScrollBar;
                  class QAbstractScrollArea;
                  class TopScrollBarWidget : public QWidget {
                      Q_OBJECT
                  
                  public:
                      TopScrollBarWidget(QAbstractScrollArea *mainWidget, bool hideBottomScrollBar = true, QWidget *parent = nullptr);
                      ~TopScrollBarWidget() = default;
                  
                  public slots:
                      void onRangeChanged(int min, int max);
                  
                  private:
                      QScrollBar          *_topHorizontalBar;
                      QAbstractScrollArea *_mainWidget;
                  };
                  

                  cpp:

                  #include <QVBoxLayout>
                  TopScrollBarWidget::TopScrollBarWidget(QAbstractScrollArea *mainWidget, bool hideBottomScrollBar, QWidget *parent) :
                      QWidget(parent),
                      _topHorizontalBar(new QScrollBar(Qt::Horizontal, this)),
                      _mainWidget(mainWidget)
                  {
                      QVBoxLayout *layout = new QVBoxLayout(this);
                      layout->addWidget(_topHorizontalBar);
                      layout->addWidget(mainWidget);
                      layout->setContentsMargins(0, 0, 0, 2);
                  
                      QScrollBar *bottomBar = mainWidget->horizontalScrollBar();
                      connect(bottomBar,         &QAbstractSlider::valueChanged, _topHorizontalBar, &QAbstractSlider::setValue);
                      connect(_topHorizontalBar, &QAbstractSlider::valueChanged, bottomBar,         &QAbstractSlider::setValue);
                      connect(bottomBar,         &QScrollBar::rangeChanged,      this,              &TopScrollBarWidget::onRangeChanged);
                  
                      if (hideBottomScrollBar)
                          _mainWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAlwaysOff);
                  }
                  
                  void TopScrollBarWidget::onRangeChanged(int min, int max)
                  {
                      _topHorizontalBar->setMinimum(min);
                      _topHorizontalBar->setMaximum(max);
                  
                      _topHorizontalBar->setVisible(min < max); //min = max = 0 if not needed ;)
                  }
                  
                  1 Reply Last reply
                  1
                  • mrjjM Offline
                    mrjjM Offline
                    mrjj
                    Lifetime Qt Champion
                    wrote on last edited by
                    #9

                    Hi
                    You are most welcome. Thank you for sharing the solution as
                    the use case might be pretty common and it is indeed not optimal
                    having to scroll all the way to the bottom
                    to be able to scroll sideways.

                    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