How to set a custom style into the QScrollBar of a QScrollArea?
-
I have created a custom
QProxyStyle"ScrollBarStyle" and im setting it on the vertical scrollbar of a QScrollAreabut the functions
drawControl/drawComplexControlnever get called, i also tried usingQCommonStyle, same problem.What I'm missing?
class ScrollBarStyle : public QProxyStyle { public: void drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const override { qDebug() << "element: " << element; if (element == CE_ScrollBarSlider) { const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(option); if (slider) { } } else { QProxyStyle::drawControl(element, option, painter, widget); } } void drawComplexControl(ComplexControl control, const QStyleOptionComplex* option, QPainter* painter, const QWidget* widget) const override { qDebug() << "control: " << control; if (control == CC_ScrollBar && option->state & State_Horizontal) { const QStyleOptionSlider* sliderOption = qstyleoption_cast<const QStyleOptionSlider*>(option); if (sliderOption) { QRect handleRect = subControlRect(control, option, SC_ScrollBarSlider, widget); painter->setBrush(Qt::red); painter->drawRect(handleRect); return; } } QProxyStyle::drawComplexControl(control, option, painter, widget); } }; class ScrollArea : public QScrollArea { Q_OBJECT public: ScrollArea(QWidget* parent = 0) : QScrollArea(parent) { //this->setStyle(new ScrollBarStyle); this->horizontalScrollBar()->setStyle(new ScrollBarStyle); } } -
I have created a custom
QProxyStyle"ScrollBarStyle" and im setting it on the vertical scrollbar of a QScrollAreabut the functions
drawControl/drawComplexControlnever get called, i also tried usingQCommonStyle, same problem.What I'm missing?
class ScrollBarStyle : public QProxyStyle { public: void drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const override { qDebug() << "element: " << element; if (element == CE_ScrollBarSlider) { const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(option); if (slider) { } } else { QProxyStyle::drawControl(element, option, painter, widget); } } void drawComplexControl(ComplexControl control, const QStyleOptionComplex* option, QPainter* painter, const QWidget* widget) const override { qDebug() << "control: " << control; if (control == CC_ScrollBar && option->state & State_Horizontal) { const QStyleOptionSlider* sliderOption = qstyleoption_cast<const QStyleOptionSlider*>(option); if (sliderOption) { QRect handleRect = subControlRect(control, option, SC_ScrollBarSlider, widget); painter->setBrush(Qt::red); painter->drawRect(handleRect); return; } } QProxyStyle::drawComplexControl(control, option, painter, widget); } }; class ScrollArea : public QScrollArea { Q_OBJECT public: ScrollArea(QWidget* parent = 0) : QScrollArea(parent) { //this->setStyle(new ScrollBarStyle); this->horizontalScrollBar()->setStyle(new ScrollBarStyle); } }@Cesar said in How to set a custom style into the QScrollBar of a QScrollArea?:
void drawControl(ControlElement element, const QStyleOption *option,
QPainter *painter, const QWidget *widget) constI guess override is missing.
void drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const override { } void drawComplexControl(ComplexControl control, const QStyleOptionComplex* option, QPainter* painter, const QWidget* widget) const override { } -
@Cesar said in How to set a custom style into the QScrollBar of a QScrollArea?:
void drawControl(ControlElement element, const QStyleOption *option,
QPainter *painter, const QWidget *widget) constI guess override is missing.
void drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const override { } void drawComplexControl(ComplexControl control, const QStyleOptionComplex* option, QPainter* painter, const QWidget* widget) const override { } -
@JoeCFD I'm already overriding them, its because i copied the functions in the cpp directly into the post, ill edit the post.
@Cesar I tried to replicate this on my end, I have a
QMainWindow, and adding aScrollAreato it did not work as you said,drawControl()did not get called.But it did work when I set its Style in
mainWindow.TQScrollArea *area = new TQScrollArea(this); area->setStyle(new ScrollBarStyle); //adding this line made it workDoes this work for you?
-
@Cesar I tried to replicate this on my end, I have a
QMainWindow, and adding aScrollAreato it did not work as you said,drawControl()did not get called.But it did work when I set its Style in
mainWindow.TQScrollArea *area = new TQScrollArea(this); area->setStyle(new ScrollBarStyle); //adding this line made it workDoes this work for you?
@Abderrahmene_Rayene said in How to set a custom style into the QScrollBar of a QScrollArea?:
TQScrollArea *area = new TQScrollArea(this);
area->setStyle(new ScrollBarStyle); //adding this line made it work
I didnt understand, you applied the style in the
QScrollArea? or in theQMainWIndow? -
@Abderrahmene_Rayene said in How to set a custom style into the QScrollBar of a QScrollArea?:
TQScrollArea *area = new TQScrollArea(this);
area->setStyle(new ScrollBarStyle); //adding this line made it work
I didnt understand, you applied the style in the
QScrollArea? or in theQMainWIndow? -
@Abderrahmene_Rayene even adding it to the QMainWindow it isnt getting called, adding it as
qApp->setStyle()onlydrawControlget called, but neverCE_ScrollBarSliderIn this similar question someone mentioned to do exactly what i tried, reimplementing the drawComplexControl.
And in this question he mentioned about needing to reset
Qt::WA_OpaquePaintEventto get the style working, but i didn't understand what he mean which "reset". -
@Abderrahmene_Rayene even adding it to the QMainWindow it isnt getting called, adding it as
qApp->setStyle()onlydrawControlget called, but neverCE_ScrollBarSliderIn this similar question someone mentioned to do exactly what i tried, reimplementing the drawComplexControl.
And in this question he mentioned about needing to reset
Qt::WA_OpaquePaintEventto get the style working, but i didn't understand what he mean which "reset". -
@Abderrahmene_Rayene even adding it to the QMainWindow it isnt getting called, adding it as
qApp->setStyle()onlydrawControlget called, but neverCE_ScrollBarSliderIn this similar question someone mentioned to do exactly what i tried, reimplementing the drawComplexControl.
And in this question he mentioned about needing to reset
Qt::WA_OpaquePaintEventto get the style working, but i didn't understand what he mean which "reset".@Cesar I had an idea, what if the reason it's not getting called is because there is no
scrollBarto draw, so I added this line inQMainWindow:area->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);and it worked, both functions got called,
drawControl/drawComplexControl -
@Cesar I had an idea, what if the reason it's not getting called is because there is no
scrollBarto draw, so I added this line inQMainWindow:area->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);and it worked, both functions got called,
drawControl/drawComplexControl -
@Abderrahmene_Rayene i already had the flag
ScrollBarAlwaysOnset on, and im testing with a QScrollArea that the QScrollBar is visible.At my side its still not getting called, even applying the style on the QMainWindow / QScrollArea QScrollBar
-
@Cesar Then there's something else you should mention, because it does call
drawComplexon my end, after I replicated what you posted, and the ScrollBar is drawn red and without arrows.This is how it looks like:

@Abderrahmene_Rayene
You don't put a debug inside theif (sliderOption)to tell us, but are you saying thatconst QStyleOptionSlider* sliderOption = qstyleoption_cast<const QStyleOptionSlider*>(option);is returning
nullptr/so false for theif? You never get tofprintf(stderr,"innercomplex\n");? -
@Abderrahmene_Rayene
You don't put a debug inside theif (sliderOption)to tell us, but are you saying thatconst QStyleOptionSlider* sliderOption = qstyleoption_cast<const QStyleOptionSlider*>(option);is returning
nullptr/so false for theif? You never get tofprintf(stderr,"innercomplex\n");? -
@Cesar Then there's something else you should mention, because it does call
drawComplexon my end, after I replicated what you posted, and the ScrollBar is drawn red and without arrows.This is how it looks like:

@Abderrahmene_Rayene said in How to set a custom style into the QScrollBar of a QScrollArea?:
if (control == CC_ScrollBar && option->state & State_Horizontal)Where do you (or the OP) get
option->state & State_Horizontalfrom? I see Qt::Orientation QStyleOptionSlider::orientation? Do not assumeQStyle::State_Horizontalis what you need for aQScrollbar.... -
@Abderrahmene_Rayene said in How to set a custom style into the QScrollBar of a QScrollArea?:
if (control == CC_ScrollBar && option->state & State_Horizontal)Where do you (or the OP) get
option->state & State_Horizontalfrom? I see Qt::Orientation QStyleOptionSlider::orientation? Do not assumeQStyle::State_Horizontalis what you need for aQScrollbar....@JonB OP is using this function:
[override virtual] void QProxyStyle::drawComplexControl(QStyle::ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget = nullptr) constwhich should get called to draw the scrollBar.
As for
State_Horizontal, it didn't work for me because I was setting the style for the vertical scroll bar, my bad. It works fine with the horizontal scroll bar. So why shouldn't one use it forQScrollBar.Sorry for the over-editing, I'm replying and testing simultaneously, I have included an image to display the outcome, it works fine, I can't replicate OP's problem.
-
@Cesar Then there's something else you should mention, because it does call
drawComplexon my end, after I replicated what you posted, and the ScrollBar is drawn red and without arrows.This is how it looks like:

-
@Abderrahmene_Rayene im not sure if i understood what you did, could you post a reproducible example of the code you're using?
@Cesar I had
TQScrollAreaandScrollBarStylein a separate header file, but I included them in themainwindowheader so that I don't post 3 files contents.mainwindow.cpp:
#include "mainwindow.h" #include "./ui_mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); TQScrollArea *area = new TQScrollArea(this); QWidget *widget = new QWidget(); widget->setGeometry(0,0,700,400); area->setWidget(widget); area->horizontalScrollBar()->setStyle(new ScrollBarStyle); area->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); area->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn); area->setGeometry(0,0,500,300); } MainWindow::~MainWindow() { delete ui; }mainwindow.h:
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QWidget> #include <QScrollArea> #include <QObject> #include <QWidget> #include <QScrollBar> #include <QDebug> #include <QStyleOptionSlider> #include <QPainter> #include <QProxyStyle> class ScrollBarStyle : public QProxyStyle { public: void drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const override { fprintf(stderr,"before\n"); if (element == CE_ScrollBarSlider) { fprintf(stderr,"after\n"); const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(option); if (slider) { } } else { QProxyStyle::drawControl(element, option, painter, widget); } } void drawComplexControl(ComplexControl control, const QStyleOptionComplex* option, QPainter* painter, const QWidget* widget) const override { fprintf(stderr,"beforecomplex\n"); if (control == CC_ScrollBar && option->state & State_Horizontal) { fprintf(stderr,"aftercomplex\n"); const QStyleOptionSlider* sliderOption = qstyleoption_cast<const QStyleOptionSlider*>(option); if (sliderOption) { fprintf(stderr,"innercomplex\n"); QRect handleRect = subControlRect(control, option, SC_ScrollBarSlider, widget); painter->setBrush(Qt::red); painter->drawRect(handleRect); return; } } QProxyStyle::drawComplexControl(control, option, painter, widget); } }; class TQScrollArea : public QScrollArea { Q_OBJECT public: TQScrollArea(QWidget* parent = 0) : QScrollArea(parent) { this->verticalScrollBar()->setStyle(new ScrollBarStyle); } }; QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } QT_END_NAMESPACE class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); private: Ui::MainWindow *ui; }; #endif // MAINWINDOW_Hmainc.cppis just the regular autogenerated one, didn't touch it. -
@JonB OP is using this function:
[override virtual] void QProxyStyle::drawComplexControl(QStyle::ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget = nullptr) constwhich should get called to draw the scrollBar.
As for
State_Horizontal, it didn't work for me because I was setting the style for the vertical scroll bar, my bad. It works fine with the horizontal scroll bar. So why shouldn't one use it forQScrollBar.Sorry for the over-editing, I'm replying and testing simultaneously, I have included an image to display the outcome, it works fine, I can't replicate OP's problem.
@Abderrahmene_Rayene said in How to set a custom style into the QScrollBar of a QScrollArea?:
As for
State_Horizontal, it didn't work for me because I was setting the style for the vertical scroll bar, my bad. It works fine with the horizontal scroll bar. So why shouldn't one use it forQScrollBar.At the time you were saying the condition was not being entered. I didn't say
option->state & State_Horizontalwould not work, I said to check assumption, since there isa specificQStyleOptionSlider::orientation == Qt::Horizontalfor a slider style option. -
@Abderrahmene_Rayene said in How to set a custom style into the QScrollBar of a QScrollArea?:
As for
State_Horizontal, it didn't work for me because I was setting the style for the vertical scroll bar, my bad. It works fine with the horizontal scroll bar. So why shouldn't one use it forQScrollBar.At the time you were saying the condition was not being entered. I didn't say
option->state & State_Horizontalwould not work, I said to check assumption, since there isa specificQStyleOptionSlider::orientation == Qt::Horizontalfor a slider style option. -
I have created a custom
QProxyStyle"ScrollBarStyle" and im setting it on the vertical scrollbar of a QScrollAreabut the functions
drawControl/drawComplexControlnever get called, i also tried usingQCommonStyle, same problem.What I'm missing?
class ScrollBarStyle : public QProxyStyle { public: void drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const override { qDebug() << "element: " << element; if (element == CE_ScrollBarSlider) { const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(option); if (slider) { } } else { QProxyStyle::drawControl(element, option, painter, widget); } } void drawComplexControl(ComplexControl control, const QStyleOptionComplex* option, QPainter* painter, const QWidget* widget) const override { qDebug() << "control: " << control; if (control == CC_ScrollBar && option->state & State_Horizontal) { const QStyleOptionSlider* sliderOption = qstyleoption_cast<const QStyleOptionSlider*>(option); if (sliderOption) { QRect handleRect = subControlRect(control, option, SC_ScrollBarSlider, widget); painter->setBrush(Qt::red); painter->drawRect(handleRect); return; } } QProxyStyle::drawComplexControl(control, option, painter, widget); } }; class ScrollArea : public QScrollArea { Q_OBJECT public: ScrollArea(QWidget* parent = 0) : QScrollArea(parent) { //this->setStyle(new ScrollBarStyle); this->horizontalScrollBar()->setStyle(new ScrollBarStyle); } }