QScrollArea signal or virtual function for "about to show scrollbar"

  • Lifetime Qt Champion

    Is it possible to catch a signal/virtual override to know when QScrollArea
    is about to show scrollbar?

    I want to disable the scrollbar and have buttons in
    top/bottom to show when normally the side scrollbar would appear.

    i have tried 
    class ScrollbarProxy : public QScrollBar {
      explicit ScrollbarProxy(QWidget* parent = nullptr);
    public slots:
      void changeEvent(QEvent* e) override {
        qDebug() << "changeEvent" << e->type();
      void setVisible(bool visible) override {
        qDebug() << "setVisible" << visible ;    
    ui->scrollArea->setVerticalScrollBar( new ScrollbarProxy() );
    ui->scrollArea->setHorizontalScrollBar( new ScrollbarProxy() );

    In the hope i could just use setVisible but even i DONT call baseclass, the scrollbars
    are shown never the less?

    Also changeEvent did not show any info when scrollbars are shown.

    So any hints of how to intercept it if possible?

    alt text
    ( mockup )

    Basically i want to show the up/down buttons when ever the right side scrollbar would show it self.

  • Moderators


    1. scrollArea->setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
    2. button->setVisible( scrollArea->verticalScrollBar()->minimum() < scrollArea->verticalScrollBar()->maximum() );
    3. connect the corresponding button to the scrollbar's triggerAction() method. Either with QAbstractSlider::SliderSingleStepAdd or QAbstractSlider::SliderPageStepAdd to scroll down.

  • Lifetime Qt Champion


    Ah, so there is no signal.

    The issue is when to call

    I guess i must do in all cases where i insert/remove items,
    scale window etc.

    There really is no lesser hack-ish way ?

    Thank you

  • Moderators

    times to check (with the code i've provided) can be when

    1. QScrollArea receives QEvent::StyleChange or QEvent::LayoutRequest events
    2. the viewport widget resizes
    3. content widget resizes

    So you could use an event-filter, but make sure to make the check delayed.

  • Lifetime Qt Champion


    1: Are they recieved via changeEvent(QEvent* e) ?

    Thank you, i will try with eventfilter and see.

  • Qt Champions 2018

    can't you just use QAbstractSlider::rangeChanged signal?

  • Lifetime Qt Champion

    thx for both suggestions.
    rangeChanged works to some degree but fires 2 signal before even shown
    rangeChange 0 , 256
    rangeChange 0 , 0

    but Im pretty sure i can work something out if i can guess from values when it should be hidden again.

    This test code seems to do what i need and show hide the buttons as expected.

    void MainWindow::rangeChanged(int min, int max) {
      qDebug() << "rangeChange" << min << " , " << max;
      if (min < max)  {
        qDebug() << "SHOW";
      if  (min == 0 && max == 0) {
        qDebug() << "HIDE";

Log in to reply

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.