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 closedDocs seem to be sadly missing in this regard. any help appreciated.
-
I think the
(option->state & QStyle::State_On);might work
-
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.
-
Did you try
comboBox->view()->isVisible();The view is the popup widget.
Normally QStyle::State_On means its checked.
@mrjj thanks , but Im not sure this is QT6 and I think I did try this but without success
-
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::drawComplexControland 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_ComboBoxListBoxPopupand 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. -
@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::drawComplexControland 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_ComboBoxListBoxPopupand 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
-
@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(); }