Why isn't a QComboBox positioned correctly in a layout?
-
wrote on 21 Jul 2019, 08:06 last edited by
A
QComboBox
seems to be shifted under the neighbouring widget in a layout. The combo box is shifted1px
down and2px
left.Here's the code to reproduce the problem:
#include <QtGui/qpainter.h> #include <QtWidgets/qcombobox.h> #include <QtWidgets/qboxlayout.h> #include <QtWidgets/qmainwindow.h> #include <QtWidgets/qapplication.h> template <typename Base> class Rectangle : public Base { public: explicit Rectangle(QColor color) : color{color} { Base::setFixedSize(100, 20); } private: QColor color; void paintEvent(QPaintEvent *) override { QPainter{this}.fillRect(Base::rect(), color); } }; int main(int argc, char **argv) { QApplication app{argc, argv}; QMainWindow window; QWidget central; window.setCentralWidget(¢ral); QHBoxLayout layout{¢ral}; layout.setSpacing(0); layout.setContentsMargins(0, 0, 0, 0); layout.addWidget(new Rectangle<QWidget>{Qt::red}); layout.addWidget(new Rectangle<QComboBox>{Qt::blue}); window.show(); return app.exec(); }
This is what I see when the blue widget is a
QComboBox
:This is what I see when the blue widget is a plain old
QWidget
:I expect both of those screenshots to be the same (but they aren't).
I'm using macOS 10.14.5 and Qt 5.12.3.
-
wrote on 21 Jul 2019, 10:09 last edited by
I updated to Qt 5.13.0 and the issue persists. Could this be a bug?
-
wrote on 21 Jul 2019, 12:20 last edited by
I'm not even sure how to work around this bug because I can't
move
or set the margins of the combo box while it's in a layout. Do I have to manually position the widget relative to the parent and completely remove the layout? -
@Kerndog73 What do you get if you call this in Base::paintEvent()?
qDebug() << rect();
-
@Kerndog73 What do you get if you call this in Base::paintEvent()?
qDebug() << rect();
-
@Kerndog73 said in Why isn't a QComboBox positioned correctly in a layout?:
@JKSH Both the
QComboBox
and theQWidget
areQRect(0,0 100x20)
Ok, their sizes are as expected.
What about
qDebug() << geometry();
? -
@Kerndog73 said in Why isn't a QComboBox positioned correctly in a layout?:
@JKSH Both the
QComboBox
and theQWidget
areQRect(0,0 100x20)
Ok, their sizes are as expected.
What about
qDebug() << geometry();
? -
wrote on 23 Jul 2019, 00:23 last edited by
I updated to macOS 10.14.6 and the issue persists. I also found a thread about a similar issue. I might be able to use a similar solution (make the widget a little bigger and offset the painting). I'm thinking about creating a bug report but my previous bug reports have gotten no response after months so I don't think I'll bother.
-
@JKSH The
QWidget
isQRect(1,39 100x20)
and theQComboBox
isQRect(99,40 100x20)
. I think the combo box geometry should beQRect(101,39 100x20)
.@Kerndog73 said in Why isn't a QComboBox positioned correctly in a layout?:
The
QWidget
isQRect(1,39 100x20)
and theQComboBox
isQRect(99,40 100x20)
. I think the combo box geometry should beQRect(101,39 100x20)
....
I'm thinking about creating a bug report but my previous bug reports have gotten no response after months so I don't think I'll bother.
You might have better luck asking in the Interest mailing list (you must subscribe first). Qt engineers are active on that list, and might be able to explain why the offset occurs.
I might be able to use a similar solution (make the widget a little bigger and offset the painting).
That sounds like a pracctical workaround
-
@Kerndog73 said in Why isn't a QComboBox positioned correctly in a layout?:
The
QWidget
isQRect(1,39 100x20)
and theQComboBox
isQRect(99,40 100x20)
. I think the combo box geometry should beQRect(101,39 100x20)
....
I'm thinking about creating a bug report but my previous bug reports have gotten no response after months so I don't think I'll bother.
You might have better luck asking in the Interest mailing list (you must subscribe first). Qt engineers are active on that list, and might be able to explain why the offset occurs.
I might be able to use a similar solution (make the widget a little bigger and offset the painting).
That sounds like a pracctical workaround
wrote on 23 Jul 2019, 00:49 last edited by@JKSH said in Why isn't a QComboBox positioned correctly in a layout?:
You might have better luck asking in the Interest mailing list (you must subscribe first).
I'll give it a try!
-
wrote on 28 Oct 2019, 14:44 last edited by MrKozmon
I think the problem is because of this piece of code from qtbase/src/plugins/styles/mac/qmacstyle_mac.mm file. Somehow they call
setLayoutItemMargins(...)
function under theSE_ComboBoxLayoutItem
case statement and it breaks QComboBox's alignment in a layout. I had this problem today and I fixed it after I removed the case statement in my own custom subclass ofQMacStyle
.In order to fix the problem, you have 3 options:
- Set
Qt::WA_LayoutUsesWidgetRect
attribute true on the comboBox:
comboBox->setAttribute(Qt::WA_LayoutUsesWidgetRect);
- Set your application style to something else, like fusion style:
QApplication::setStyle("fusion");
-
Implement your own custom style class based on
QMacStyle
viaQProxyStyle
(which is the way I do), then reimplementsubElementRect(...)
function and make sure the function returns an invalid/default constructedQRect()
forSE_ComboBoxLayoutItem
case. Finally set your application style to your own custom style class. -
BONUS (pretty nasty option): As a bonus option, you can follow the "hacky" way below:
4.1. AddQT += widgets-private
to your .pro file
4.2. Insert the comboBox to the layout
4.3. CallsetLayoutItemMargins(...)
function of thecomboBox
#include <private/qwidget_p.h> class Hacker : public QWidget { public: Q_DECLARE_PRIVATE(QWidget) }; reinterpret_cast<Hacker*>(comboBox)->d_func()->setLayoutItemMargins(0, 0, 0, 0); // Might be an undefined behavior based on C++ standards
- Set