Ensure that layouts don't move widgets outside of their parent
When using a style that wants to draw into the layout's margin (like macOS style does with group box titles), parts of the widgets would be clipped by the parent if the available margin is smaller than necessary. This moves the x/y coordinates to at least 0/0, and adjusts width and height accordingly. [ChangeLog][QtWidgets][QLayout] Prevent clipping of group box titles on macOS (and similar styles that draw into layout margins) Change-Id: I32148a92858c13fb2325da4d0a2a58996e0e8930 Fixes: QTBUG-67608 Reviewed-by: Paul Olav Tvete <paul.tvete@qt.io>bb10
parent
4054759aec
commit
d0f016ebfb
|
|
@ -502,6 +502,17 @@ void QWidgetItem::setGeometry(const QRect &rect)
|
|||
else if (!(align & Qt::AlignTop))
|
||||
y = y + (r.height() - s.height()) / 2;
|
||||
|
||||
// Make sure we don't move outside of the parent, e.g when styles demand
|
||||
// surplus space that exceeds the available margins (f.ex macOS with QGroupBox)
|
||||
if (x < 0) {
|
||||
s.rwidth() += x;
|
||||
x = 0;
|
||||
}
|
||||
if (y < 0) {
|
||||
s.rheight() += y;
|
||||
y = 0;
|
||||
}
|
||||
|
||||
wid->setGeometry(x, y, s.width(), s.height());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ private slots:
|
|||
void sizeConstraints();
|
||||
void setGeometry();
|
||||
void setStyleShouldChangeSpacing();
|
||||
void widgetSurplus();
|
||||
|
||||
void testLayoutEngine_data();
|
||||
void testLayoutEngine();
|
||||
|
|
@ -236,6 +237,69 @@ void tst_QBoxLayout::setStyleShouldChangeSpacing()
|
|||
QTRY_COMPARE(spacing(), 10);
|
||||
}
|
||||
|
||||
class MarginEatingStyle : public QProxyStyle
|
||||
{
|
||||
public:
|
||||
MarginEatingStyle() : QProxyStyle(QStyleFactory::create("windows"))
|
||||
{
|
||||
}
|
||||
|
||||
virtual QRect subElementRect(SubElement sr, const QStyleOption *opt,
|
||||
const QWidget *widget) const
|
||||
{
|
||||
QRect rect = opt->rect;
|
||||
switch (sr) {
|
||||
case SE_GroupBoxLayoutItem:
|
||||
// this is a simplifed version of what the macOS style does
|
||||
rect.setTop(rect.top() + 20);
|
||||
rect.setLeft(rect.left() + 20);
|
||||
rect.setRight(rect.right() - 20);
|
||||
rect.setBottom(rect.bottom() - 20);
|
||||
break;
|
||||
default:
|
||||
return QProxyStyle::subElementRect(sr, opt, widget);
|
||||
}
|
||||
|
||||
return rect;
|
||||
}
|
||||
};
|
||||
|
||||
void tst_QBoxLayout::widgetSurplus()
|
||||
{
|
||||
// Test case for QTBUG-67608 - a style requests space in the margin
|
||||
|
||||
QDialog window;
|
||||
QScopedPointer<MarginEatingStyle> marginEater(new MarginEatingStyle);
|
||||
QVBoxLayout *vbox = new QVBoxLayout(&window);
|
||||
vbox->setMargin(0);
|
||||
vbox->setSpacing(0);
|
||||
|
||||
QLabel *hiddenLabel = new QLabel(tr("Invisible label"));
|
||||
hiddenLabel->setVisible(false);
|
||||
|
||||
QGroupBox *groupBox = new QGroupBox(tr("Groupbox Title"));
|
||||
groupBox->setStyle(marginEater.data());
|
||||
groupBox->setObjectName("Test group box");
|
||||
QPushButton *button1 = new QPushButton(tr("Button 1"));
|
||||
QPushButton *button2 = new QPushButton(tr("Button 2"));
|
||||
QVBoxLayout *groupLayout = new QVBoxLayout;
|
||||
groupLayout->addWidget(button1);
|
||||
groupLayout->addWidget(button2);
|
||||
groupBox->setLayout(groupLayout);
|
||||
|
||||
QLabel *label = new QLabel(tr("Visible label"));
|
||||
|
||||
vbox->addWidget(hiddenLabel);
|
||||
vbox->addWidget(groupBox);
|
||||
vbox->addWidget(label);
|
||||
window.setLayout(vbox);
|
||||
|
||||
window.show();
|
||||
QVERIFY(QTest::qWaitForWindowExposed(&window));
|
||||
QCOMPARE(groupBox->y(), 0);
|
||||
QCOMPARE(groupBox->x(), 0);
|
||||
}
|
||||
|
||||
void tst_QBoxLayout::taskQTBUG_7103_minMaxWidthNotRespected()
|
||||
{
|
||||
QLabel *label = new QLabel("Qt uses standard C++, but makes extensive use of the C pre-processor to enrich the language. Qt can also be used in several other programming languages via language bindings. It runs on all major platforms, and has extensive internationalization support. Non-GUI features include SQL database access, XML parsing, thread management, network support and a unified cross-platform API for file handling.");
|
||||
|
|
|
|||
Loading…
Reference in New Issue