QT6 QComboBox open in drawComplexControl
-
Hi All ,
I have a derived QProxyStyle::drawComplexControl function I would like to check if the comboBox is open using QT6,switch (control) { case CC_SpinBox: { QProxyStyle::drawComplexControl(control, option, painter, widget); break; } case CC_ComboBox: { const auto comboOption = qstyleoption_cast<const QStyleOptionComboBox *>(option); const auto comboBox = qobject_cast<QComboBox*>(const_cast<QWidget*>(widget)); bool animate = true; if(!comboBox)return; // ... test if comboBox open or closed
Docs seem to be sadly missing in this regard. any help appreciated.
-
I think the
(option->state & QStyle::State_On);
might work
-
Did you try
comboBox->view()->isVisible();The view is the popup widget.
Normally QStyle::State_On means its checked.
-
@mrjj said in QT6 QComboBox open in drawComplexControl:
comboBox->view()->isVisible();
isVisible()
always gives the right answer. If asked the right question, at the right time, from the right place ;-)I have a derived QProxyStyle::drawComplexControl function
QStyle::drawComplexControl
and overrides are called to draw the combobox with the arrow down symbol, i.e. when it is not launched. Even ifcomboBox->view()->isVisible()
returns true, an item could have been already selected and the view is meant to disappear. If a view is to be newly drawn, it is still likely to returnfalse
, if the drawing isn't finished and the view hasn't been shown before.The view itself is drawn elsewhere and the location depends on your platform. You may want to search for
SC_ComboBoxListBoxPopup
and set breakpoints. Then you will see which code path is entered to draw the view and how you can inject you own implementation in the derived class. -
@Axel-Spoerl thanks, good to know more the inner workings. but for this case the (option->state & QStyle::State_On); seems the best choice especially as styling the tab is based on the state that its active /on
-
@TrilecStudios for the sake of completeness:
This is the current implementation for those interested.
//a simple implementation the calls the styling function void CharcoalStyle::drawComplexControl(ComplexControl control, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget) const { switch (control) { case CC_ComboBox: { setComboboxStyle(option, painter, widget ) ; break; } default: QProxyStyle::drawComplexControl(control, option, painter, widget); break; } } //the basic implementation of drawing a style for combobox void CharcoalStyle::setComboboxStyle(const QStyleOption *option, QPainter* painter, const QWidget *widget) const { const auto comboOption = qstyleoption_cast<const QStyleOptionComboBox *>(option); const auto comboBox = qobject_cast<QComboBox*>(const_cast<QWidget*>(widget)); if(!comboOption ) return; bool isDown = (option->state & QStyle::State_Sunken); bool isEnabled = (option->state & QStyle::State_Enabled); bool hasFocus = (option->state & QStyle::State_HasFocus && option->state & QStyle::State_KeyboardFocusChange); bool isOver = (option->state & QStyle::State_MouseOver); bool isOn = (option->state & QStyle::State_On); enum DESIGN { NormalDesign = 0, FlatDesign = 1, Design1 = 2, Design2 = 3 }; int design = NormalDesign; QColor bgColor = ComboboxBg; QColor fgColor = ComboboxFg; QColor borderColor = ComboBoxBorder; QColor iconColor = ComboBoxIcon; QRect rect = comboOption->rect; // prepare and load existing defaults QFont font = comboBox->font(); Qt::Alignment alignment = Qt::AlignLeft | Qt::AlignVCenter; // override any additional settings to take care of a design property being set (defined in header) if (comboBox->property(Design1Property.toStdString().c_str()).toBool()) { design = Design1; bgColor = design1Bg; fgColor = design1Fg; borderColor = design1Border; iconColor = design1Icon; } // design = NormalDesign; //defined at top of function as default // ajust the colours if it's on to being slightly brighter for on state if( isDown ) { bgColor = bgColor.lighter(140); fgColor = fgColor.lighter(110); borderColor = borderColor.lighter(110); iconColor = iconColor.lighter(110); } // ajust the colours on a disabled state adjusting saturation, lightness and transparency if( !isEnabled ) { // Convert the base color to HSL and adjust the saturation and brightness bgColor = QColor::fromHslF(bgColor.hslHueF(), bgColor.hslSaturationF() * 0.7, bgColor.lightnessF() * 0.8); fgColor = QColor::fromHslF(fgColor.hslHueF(), fgColor.hslSaturationF() * 0.7, fgColor.lightnessF() * 0.8); iconColor = QColor::fromHslF(iconColor.hslHueF(), iconColor.hslSaturationF() * 0.7, iconColor.lightnessF() * 0.8); bgColor.setAlpha(128); //a little bit of transparency borderColor = bgColor; } // ajust the colours if we are hovering over the button or widget if( isOver ) { bgColor = bgColor.lighter(112); fgColor = fgColor.lighter(112); borderColor = borderColor.lighter(112); iconColor = iconColor.lighter(112); } //setup the painter painter->save(); //painter->setRenderHint(QPainter::Antialiasing); painter->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform); painter->setBrush(bgColor); painter->setFont(font); //path handles anti-aliasing a lot better specially for rounded QPainterPath path; // draw the appropriate style switch (design) { case Design1: path.addRect( rect ); painter->setPen(QPen( borderColor,2 )); if( isOn ) { painter->drawPath(path); drawArrow( painter, Qt::DownArrow, rect, comboOption,iconColor); } else { painter->fillPath(path, bgColor); drawArrow( painter, Qt::RightArrow, rect, comboOption,iconColor); } painter->setPen(QPen(fgColor, 1)); painter->drawText(rect.adjusted(4, 0, -18, 0), alignment, comboOption->currentText); break; default: painter->setPen(QPen( borderColor,1 )); qreal radius = option->rect.height() / 2; path.addRoundedRect(rect, radius,radius); if( isOn ) { painter->drawPath(path); painter->setBrush(bgColor); drawArrow( painter, Qt::DownArrow, rect, comboOption,iconColor); } else { painter->fillPath(path, bgColor); drawArrow( painter, Qt::RightArrow, rect, comboOption,iconColor); } painter->setPen(QPen(fgColor, 1)); painter->drawText(rect.adjusted( radius , 0, -18, 0), alignment, comboOption->currentText); break; } painter->restore(); }