mirror of
https://github.com/crystalidea/qt6windows7.git
synced 2025-07-05 08:45:25 +08:00
qt 6.5.1 original
This commit is contained in:
@ -0,0 +1,16 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## tst_qgraphicslayout Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qgraphicslayout
|
||||
SOURCES
|
||||
tst_qgraphicslayout.cpp
|
||||
DEFINES
|
||||
QT_USE_USING_NAMESPACE
|
||||
LIBRARIES
|
||||
Qt::Gui
|
||||
Qt::Widgets
|
||||
)
|
@ -0,0 +1,980 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
|
||||
#include <QTest>
|
||||
#include <QtGui>
|
||||
#include <QtWidgets>
|
||||
#include <math.h>
|
||||
|
||||
class tst_QGraphicsLayout : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
tst_QGraphicsLayout();
|
||||
virtual ~tst_QGraphicsLayout();
|
||||
|
||||
private slots:
|
||||
void sizeHints();
|
||||
void compressLayoutRequest();
|
||||
void automaticReparenting();
|
||||
void verifyActivate();
|
||||
void sizeHintOfHiddenLayout();
|
||||
void invalidate();
|
||||
void constructors();
|
||||
void alternativeLayoutItems();
|
||||
void ownership();
|
||||
};
|
||||
|
||||
tst_QGraphicsLayout::tst_QGraphicsLayout()
|
||||
{
|
||||
}
|
||||
|
||||
tst_QGraphicsLayout::~tst_QGraphicsLayout()
|
||||
{
|
||||
}
|
||||
|
||||
void tst_QGraphicsLayout::sizeHints()
|
||||
{
|
||||
|
||||
QGraphicsView view;
|
||||
QGraphicsScene scene;
|
||||
QGraphicsWidget *window = new QGraphicsWidget();
|
||||
scene.addItem(window);
|
||||
QGraphicsLinearLayout *lout = new QGraphicsLinearLayout(window);
|
||||
lout->setContentsMargins(0,0,0,0);
|
||||
QGraphicsWidget *gw = new QGraphicsWidget(window);
|
||||
gw->setMinimumSize(QSizeF(10,10));
|
||||
gw->setPreferredSize(QSizeF(100,100));
|
||||
gw->setMaximumSize(QSizeF(500,500));
|
||||
lout->addItem(gw);
|
||||
QCOMPARE(lout->effectiveSizeHint(Qt::MinimumSize), gw->effectiveSizeHint(Qt::MinimumSize));
|
||||
QCOMPARE(lout->effectiveSizeHint(Qt::PreferredSize), gw->effectiveSizeHint(Qt::PreferredSize));
|
||||
QCOMPARE(lout->effectiveSizeHint(Qt::MaximumSize), gw->effectiveSizeHint(Qt::MaximumSize));
|
||||
|
||||
}
|
||||
|
||||
enum FunctionType {
|
||||
SetGeometry = 0,
|
||||
Invalidate,
|
||||
NumFunctionTypes
|
||||
};
|
||||
|
||||
|
||||
|
||||
class TestGraphicsWidget : public QGraphicsWidget {
|
||||
public:
|
||||
TestGraphicsWidget(QGraphicsWidget *parent = nullptr) : QGraphicsWidget(parent)
|
||||
{ }
|
||||
|
||||
bool event(QEvent *e) override
|
||||
{
|
||||
++(m_eventCount[int(e->type())]);
|
||||
return QGraphicsWidget::event(e);
|
||||
}
|
||||
|
||||
int eventCount(QEvent::Type type) {
|
||||
return m_eventCount.value(int(type));
|
||||
}
|
||||
|
||||
void clearEventCount() {
|
||||
m_eventCount.clear();
|
||||
}
|
||||
|
||||
void clearCounters() {
|
||||
m_eventCount.clear();
|
||||
functionCount.clear();
|
||||
}
|
||||
|
||||
void setGeometry(const QRectF &rect) override
|
||||
{
|
||||
QGraphicsWidget::setGeometry(rect);
|
||||
++(functionCount[SetGeometry]);
|
||||
}
|
||||
|
||||
void callUpdateGeometry()
|
||||
{
|
||||
// updateGeometry() is protected
|
||||
QGraphicsWidget::updateGeometry();
|
||||
}
|
||||
QMap<FunctionType, int> functionCount;
|
||||
private:
|
||||
QMap<int, int> m_eventCount;
|
||||
};
|
||||
|
||||
void tst_QGraphicsLayout::compressLayoutRequest()
|
||||
{
|
||||
QGraphicsView view;
|
||||
QGraphicsScene scene;
|
||||
TestGraphicsWidget *tw = new TestGraphicsWidget();
|
||||
scene.addItem(tw);
|
||||
view.show();
|
||||
|
||||
QVERIFY(QTest::qWaitForWindowExposed(&view));
|
||||
QGraphicsLinearLayout *lout = new QGraphicsLinearLayout(tw);
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
QGraphicsWidget *gw = new QGraphicsWidget(tw);
|
||||
gw->setPreferredSize(QSizeF(50, 50));
|
||||
lout->addItem(gw);
|
||||
}
|
||||
QApplication::processEvents();
|
||||
QCOMPARE(tw->eventCount(QEvent::LayoutRequest), 1);
|
||||
}
|
||||
|
||||
void tst_QGraphicsLayout::automaticReparenting()
|
||||
{
|
||||
QGraphicsView view;
|
||||
QGraphicsScene scene;
|
||||
{
|
||||
QGraphicsWidget *w = new QGraphicsWidget();
|
||||
QGraphicsLinearLayout *l = new QGraphicsLinearLayout(w);
|
||||
QGraphicsWidget *w1 = new QGraphicsWidget;
|
||||
l->addItem(w1);
|
||||
scene.addItem(w);
|
||||
QCOMPARE(w1->parentWidget(), w);
|
||||
delete w;
|
||||
}
|
||||
{
|
||||
QGraphicsWidget *w = new QGraphicsWidget();
|
||||
QGraphicsLinearLayout *l = new QGraphicsLinearLayout(w);
|
||||
QGraphicsWidget *w1 = new QGraphicsWidget;
|
||||
l->addItem(w1);
|
||||
scene.addItem(w);
|
||||
QCOMPARE(w1->parentWidget(), w);
|
||||
|
||||
QGraphicsWidget *ww = new QGraphicsWidget();
|
||||
QGraphicsLinearLayout *l1 = new QGraphicsLinearLayout(ww);
|
||||
#if !defined(Q_OS_MAC) && defined(QT_DEBUG)
|
||||
QTest::ignoreMessage(QtWarningMsg, "QGraphicsLayout::addChildLayoutItem: QGraphicsWidget \"\""
|
||||
" in wrong parent; moved to correct parent");
|
||||
#endif
|
||||
l1->addItem(w1);
|
||||
QCOMPARE(w1->parentWidget(), ww);
|
||||
delete w;
|
||||
}
|
||||
|
||||
QGraphicsWidget *window = new QGraphicsWidget();
|
||||
scene.addItem(window);
|
||||
view.show();
|
||||
QGraphicsLinearLayout *l1 = new QGraphicsLinearLayout();
|
||||
QGraphicsWidget *w1 = new QGraphicsWidget();
|
||||
l1->addItem(w1);
|
||||
QGraphicsWidget *w2 = new QGraphicsWidget();
|
||||
l1->addItem(w2);
|
||||
QCOMPARE(w1->parentItem(), nullptr);
|
||||
QCOMPARE(w2->parentItem(), nullptr);
|
||||
scene.addItem(w1);
|
||||
QCOMPARE(w1->parentItem(), nullptr);
|
||||
window->setLayout(l1);
|
||||
QCOMPARE(w1->parentItem(), static_cast<QGraphicsItem*>(window));
|
||||
QCOMPARE(w2->parentItem(), static_cast<QGraphicsItem*>(window));
|
||||
|
||||
// Sublayouts
|
||||
QGraphicsLinearLayout *l2 = new QGraphicsLinearLayout();
|
||||
QGraphicsWidget *w3 = new QGraphicsWidget();
|
||||
l2->addItem(w3);
|
||||
QGraphicsWidget *w4 = new QGraphicsWidget();
|
||||
l2->addItem(w4);
|
||||
QGraphicsLinearLayout *l3 = new QGraphicsLinearLayout();
|
||||
l2->addItem(l3);
|
||||
QGraphicsWidget *window2 = new QGraphicsWidget();
|
||||
scene.addItem(window2);
|
||||
window2->setLayout(l2);
|
||||
|
||||
QCOMPARE(w3->parentItem(), static_cast<QGraphicsItem*>(window2));
|
||||
QCOMPARE(w4->parentItem(), static_cast<QGraphicsItem*>(window2));
|
||||
|
||||
// graphics item with another parent
|
||||
QGraphicsLinearLayout *l5 = new QGraphicsLinearLayout();
|
||||
l5->addItem(w1);
|
||||
l5->addItem(w2);
|
||||
QCOMPARE(w1->parentItem(), static_cast<QGraphicsItem*>(window));
|
||||
QCOMPARE(w2->parentItem(), static_cast<QGraphicsItem*>(window));
|
||||
QGraphicsLinearLayout *l4 = new QGraphicsLinearLayout();
|
||||
l4->addItem(l5);
|
||||
QGraphicsWidget *window3 = new QGraphicsWidget();
|
||||
scene.addItem(window3);
|
||||
window3->setLayout(l4);
|
||||
|
||||
QCOMPARE(w1->parentItem(), static_cast<QGraphicsItem*>(window3));
|
||||
QCOMPARE(w2->parentItem(), static_cast<QGraphicsItem*>(window3));
|
||||
}
|
||||
|
||||
class TestLayout : public QGraphicsLinearLayout
|
||||
{
|
||||
public:
|
||||
TestLayout(QGraphicsLayoutItem *parent = nullptr)
|
||||
: QGraphicsLinearLayout(parent)
|
||||
{
|
||||
setContentsMargins(0,0,0,0);
|
||||
setSpacing(0);
|
||||
}
|
||||
|
||||
void setGeometry(const QRectF &rect) override
|
||||
{
|
||||
++(functionCount[SetGeometry]);
|
||||
QGraphicsLinearLayout::setGeometry(rect);
|
||||
}
|
||||
|
||||
void invalidate() override
|
||||
{
|
||||
++(functionCount[Invalidate]);
|
||||
QGraphicsLinearLayout::invalidate();
|
||||
}
|
||||
|
||||
void clearCounters() {
|
||||
functionCount.clear();
|
||||
}
|
||||
|
||||
QMap<FunctionType, int> functionCount;
|
||||
};
|
||||
|
||||
void tst_QGraphicsLayout::verifyActivate()
|
||||
{
|
||||
QGraphicsScene scene;
|
||||
QGraphicsView view(&scene);
|
||||
|
||||
QGraphicsWidget *window = new QGraphicsWidget();
|
||||
scene.addItem(window);
|
||||
TestLayout *lout = new TestLayout(window);
|
||||
QGraphicsWidget *w = new QGraphicsWidget();
|
||||
lout->addItem(w);
|
||||
window->setLayout(lout);
|
||||
|
||||
QCOMPARE(lout->functionCount[SetGeometry], 0);
|
||||
window->setVisible(false);
|
||||
QCOMPARE(lout->functionCount[SetGeometry], 0);
|
||||
window->setVisible(true);
|
||||
// on polish or the first time a widget is shown, the widget is resized.
|
||||
QCOMPARE(lout->functionCount[SetGeometry], 1);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void tst_QGraphicsLayout::sizeHintOfHiddenLayout()
|
||||
{
|
||||
QGraphicsScene scene;
|
||||
QGraphicsView view(&scene);
|
||||
|
||||
QGraphicsWidget *window = new QGraphicsWidget(0, Qt::Window);
|
||||
scene.addItem(window);
|
||||
TestLayout *lout = new TestLayout(window);
|
||||
lout->setContentsMargins(1,2,2,1);
|
||||
QGraphicsWidget *w = new QGraphicsWidget;
|
||||
w->setPreferredSize(20, 20);
|
||||
w->setMaximumSize(50, 50);
|
||||
lout->addItem(w);
|
||||
window->setLayout(lout);
|
||||
|
||||
for (int pass = 0; pass < 3; ++pass) {
|
||||
QCOMPARE(lout->sizeHint(Qt::MinimumSize), QSizeF(3,3));
|
||||
QCOMPARE(lout->sizeHint(Qt::PreferredSize), QSizeF(23,23));
|
||||
QCOMPARE(lout->sizeHint(Qt::MaximumSize), QSizeF(53,53));
|
||||
window->setVisible(pass % 2);
|
||||
}
|
||||
}
|
||||
|
||||
static void clearAllCounters(TestGraphicsWidget *widget)
|
||||
{
|
||||
if (!widget)
|
||||
return;
|
||||
widget->clearCounters();
|
||||
TestLayout *layout = static_cast<TestLayout *>(widget->layout());
|
||||
if (layout) {
|
||||
layout->clearCounters();
|
||||
for (int i = layout->count() - 1; i >=0; --i) {
|
||||
QGraphicsLayoutItem *item = layout->itemAt(i);
|
||||
if (item->isLayout()) {
|
||||
// ### Not used ATM
|
||||
//TestLayout *lay = static_cast<TestLayout*>(static_cast<QGraphicsLayout*>(item));
|
||||
//clearAllCounters(lay);
|
||||
} else {
|
||||
TestGraphicsWidget *wid = static_cast<TestGraphicsWidget *>(item);
|
||||
clearAllCounters(wid);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void activateAndReset(TestGraphicsWidget *widget)
|
||||
{
|
||||
QApplication::sendPostedEvents();
|
||||
QApplication::processEvents();
|
||||
if (widget->layout())
|
||||
widget->layout()->activate();
|
||||
clearAllCounters(widget);
|
||||
}
|
||||
|
||||
|
||||
void tst_QGraphicsLayout::invalidate()
|
||||
{
|
||||
QGraphicsLayout::setInstantInvalidatePropagation(true);
|
||||
QGraphicsScene scene;
|
||||
QGraphicsView view(&scene);
|
||||
|
||||
TestGraphicsWidget *a = new TestGraphicsWidget;
|
||||
a->setData(0, QString("a"));
|
||||
scene.addItem(a);
|
||||
TestLayout *alay = new TestLayout(a);
|
||||
TestGraphicsWidget *b = new TestGraphicsWidget;
|
||||
b->setData(0, QString("b"));
|
||||
alay->addItem(b);
|
||||
TestLayout *blay = new TestLayout(b);
|
||||
TestGraphicsWidget *e = new TestGraphicsWidget;
|
||||
e->setData(0, QString("e"));
|
||||
blay->addItem(e);
|
||||
|
||||
|
||||
TestGraphicsWidget *c = new TestGraphicsWidget;
|
||||
c->setData(0, QString("c"));
|
||||
alay->addItem(c);
|
||||
TestLayout *clay = new TestLayout(c);
|
||||
TestGraphicsWidget *f = new TestGraphicsWidget;
|
||||
f->setData(0, QString("f"));
|
||||
clay->addItem(f);
|
||||
|
||||
TestGraphicsWidget *d = new TestGraphicsWidget;
|
||||
d->setData(0, QString("d"));
|
||||
alay->addItem(d);
|
||||
TestLayout *dlay = new TestLayout(d);
|
||||
TestGraphicsWidget *g = new TestGraphicsWidget;
|
||||
g->setData(0, QString("g"));
|
||||
dlay->addItem(g);
|
||||
|
||||
view.show();
|
||||
|
||||
{
|
||||
clearAllCounters(a);
|
||||
|
||||
QCoreApplication::sendPostedEvents();
|
||||
QCoreApplication::processEvents();
|
||||
|
||||
alay->activate();
|
||||
QCOMPARE(alay->isActivated(), true);
|
||||
QCOMPARE(blay->isActivated(), true);
|
||||
QCOMPARE(clay->isActivated(), true);
|
||||
QCOMPARE(dlay->isActivated(), true);
|
||||
}
|
||||
|
||||
{
|
||||
clearAllCounters(a);
|
||||
e->callUpdateGeometry();
|
||||
QCOMPARE(alay->isActivated(), false);
|
||||
QCOMPARE(blay->isActivated(), false);
|
||||
QCOMPARE(clay->isActivated(), true);
|
||||
QCOMPARE(dlay->isActivated(), true);
|
||||
QCOMPARE(a->eventCount(QEvent::LayoutRequest), 0);
|
||||
QCOMPARE(b->eventCount(QEvent::LayoutRequest), 0);
|
||||
QCOMPARE(c->eventCount(QEvent::LayoutRequest), 0);
|
||||
QCOMPARE(d->eventCount(QEvent::LayoutRequest), 0);
|
||||
|
||||
// should only invalidate ascendants of e
|
||||
QCOMPARE(blay->functionCount[Invalidate], 1);
|
||||
QCOMPARE(alay->functionCount[Invalidate], 1);
|
||||
// not siblings
|
||||
QCOMPARE(clay->functionCount[Invalidate], 0);
|
||||
QCOMPARE(dlay->functionCount[Invalidate], 0);
|
||||
|
||||
QApplication::sendPostedEvents();
|
||||
QCOMPARE(a->eventCount(QEvent::LayoutRequest), 1);
|
||||
QCOMPARE(b->eventCount(QEvent::LayoutRequest), 1);
|
||||
QCOMPARE(c->eventCount(QEvent::LayoutRequest), 0);
|
||||
QCOMPARE(d->eventCount(QEvent::LayoutRequest), 0);
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
activateAndReset(a);
|
||||
f->callUpdateGeometry();
|
||||
QCOMPARE(alay->isActivated(), false);
|
||||
QCOMPARE(blay->isActivated(), true);
|
||||
QCOMPARE(clay->isActivated(), false);
|
||||
QCOMPARE(dlay->isActivated(), true);
|
||||
|
||||
QCoreApplication::sendPostedEvents();
|
||||
QCOMPARE(a->eventCount(QEvent::LayoutRequest), 1);
|
||||
QCOMPARE(b->eventCount(QEvent::LayoutRequest), 0);
|
||||
QCOMPARE(c->eventCount(QEvent::LayoutRequest), 1);
|
||||
QCOMPARE(d->eventCount(QEvent::LayoutRequest), 0);
|
||||
|
||||
QCOMPARE(a->functionCount[SetGeometry], 1);
|
||||
QCOMPARE(alay->functionCount[SetGeometry], 1);
|
||||
|
||||
QCOMPARE(b->functionCount[SetGeometry], 1);
|
||||
QCOMPARE(c->functionCount[SetGeometry], 1);
|
||||
QCOMPARE(d->functionCount[SetGeometry], 1);
|
||||
// Since nothing really changed, blay and dlay don't need
|
||||
// to be resized.
|
||||
QCOMPARE(blay->functionCount[SetGeometry], 0);
|
||||
QCOMPARE(clay->functionCount[SetGeometry], 1);
|
||||
QCOMPARE(dlay->functionCount[SetGeometry], 0);
|
||||
|
||||
QCOMPARE(f->functionCount[SetGeometry], 1);
|
||||
|
||||
QCOMPARE(a->size(), QSizeF(150, 50));
|
||||
}
|
||||
|
||||
{
|
||||
activateAndReset(a);
|
||||
f->setPreferredSize(QSizeF(60,50));
|
||||
QCOMPARE(alay->isActivated(), false);
|
||||
QCOMPARE(blay->isActivated(), true);
|
||||
QCOMPARE(clay->isActivated(), false);
|
||||
QCOMPARE(dlay->isActivated(), true);
|
||||
|
||||
QCOMPARE(c->eventCount(QEvent::LayoutRequest), 0);
|
||||
QCoreApplication::sendPostedEvents();
|
||||
QCOMPARE(a->eventCount(QEvent::LayoutRequest), 1);
|
||||
QCOMPARE(b->eventCount(QEvent::LayoutRequest), 0);
|
||||
QCOMPARE(c->eventCount(QEvent::LayoutRequest), 1);
|
||||
QCOMPARE(d->eventCount(QEvent::LayoutRequest), 0);
|
||||
|
||||
QCOMPARE(a->functionCount[SetGeometry], 1);
|
||||
QCOMPARE(alay->functionCount[SetGeometry], 1);
|
||||
|
||||
QCOMPARE(b->functionCount[SetGeometry], 1);
|
||||
QCOMPARE(c->functionCount[SetGeometry], 1);
|
||||
QCOMPARE(d->functionCount[SetGeometry], 1);
|
||||
// f actually got wider, need to rearrange its siblings
|
||||
QCOMPARE(blay->functionCount[SetGeometry], 1);
|
||||
QCOMPARE(clay->functionCount[SetGeometry], 1);
|
||||
QCOMPARE(dlay->functionCount[SetGeometry], 1);
|
||||
|
||||
QCOMPARE(e->functionCount[SetGeometry], 1);
|
||||
QCOMPARE(f->functionCount[SetGeometry], 1);
|
||||
QCOMPARE(g->functionCount[SetGeometry], 1);
|
||||
|
||||
QVERIFY(e->size().width() < f->size().width());
|
||||
QVERIFY(g->size().width() < f->size().width());
|
||||
}
|
||||
|
||||
{
|
||||
// resize f so much that it'll force a resize of the top widget
|
||||
// this will currently generate two setGeometry() calls on the child layout
|
||||
// of the top widget.
|
||||
activateAndReset(a);
|
||||
f->setPreferredSize(QSizeF());
|
||||
f->setMinimumSize(QSizeF(200,50));
|
||||
QCOMPARE(alay->isActivated(), false);
|
||||
QCOMPARE(blay->isActivated(), true);
|
||||
QCOMPARE(clay->isActivated(), false);
|
||||
QCOMPARE(dlay->isActivated(), true);
|
||||
|
||||
QCOMPARE(c->eventCount(QEvent::LayoutRequest), 0);
|
||||
QCoreApplication::sendPostedEvents();
|
||||
QCOMPARE(a->eventCount(QEvent::LayoutRequest), 1);
|
||||
QCOMPARE(b->eventCount(QEvent::LayoutRequest), 0);
|
||||
QCOMPARE(c->eventCount(QEvent::LayoutRequest), 1);
|
||||
QCOMPARE(d->eventCount(QEvent::LayoutRequest), 0);
|
||||
|
||||
QCOMPARE(a->functionCount[SetGeometry], 1);
|
||||
|
||||
/* well, ideally one call to setGeometry(), but it will currently
|
||||
* get two calls to setGeometry():
|
||||
* 1. The first LayoutRequest will call activate() - that will call
|
||||
* setGeometry() on the layout. This geometry will be based on
|
||||
* the widget geometry which is not correct at this moment.
|
||||
* (it is still 150 wide)
|
||||
* 2. Next, we check if the widget is top level, and then we call
|
||||
* parentWidget->resize(parentWidget->size());
|
||||
* This will be adjusted to be minimum 200 pixels wide.
|
||||
* The new size will then be propagated down to the layout
|
||||
*
|
||||
*/
|
||||
QCOMPARE(alay->functionCount[SetGeometry], 2);
|
||||
|
||||
QCOMPARE(b->functionCount[SetGeometry], 2);
|
||||
QCOMPARE(c->functionCount[SetGeometry], 2);
|
||||
QCOMPARE(d->functionCount[SetGeometry], 2);
|
||||
// f actually got wider, need to rearrange its siblings
|
||||
QCOMPARE(blay->functionCount[SetGeometry], 1);
|
||||
QCOMPARE(clay->functionCount[SetGeometry], 1);
|
||||
QCOMPARE(dlay->functionCount[SetGeometry], 1);
|
||||
|
||||
QCOMPARE(e->functionCount[SetGeometry], 1);
|
||||
QCOMPARE(f->functionCount[SetGeometry], 1);
|
||||
QCOMPARE(g->functionCount[SetGeometry], 1);
|
||||
|
||||
QVERIFY(e->size().width() < f->size().width());
|
||||
QVERIFY(g->size().width() < f->size().width());
|
||||
}
|
||||
|
||||
{
|
||||
f->setPreferredSize(QSizeF());
|
||||
f->setMinimumSize(QSizeF());
|
||||
a->adjustSize();
|
||||
activateAndReset(a);
|
||||
// update two different leaf widgets,
|
||||
// eventCount and functionCount should never be >= 2
|
||||
e->callUpdateGeometry();
|
||||
g->callUpdateGeometry();
|
||||
QCOMPARE(alay->isActivated(), false);
|
||||
QCOMPARE(blay->isActivated(), false);
|
||||
QCOMPARE(clay->isActivated(), true);
|
||||
QCOMPARE(dlay->isActivated(), false);
|
||||
|
||||
QCoreApplication::sendPostedEvents();
|
||||
QCOMPARE(a->eventCount(QEvent::LayoutRequest), 1);
|
||||
QCOMPARE(b->eventCount(QEvent::LayoutRequest), 1);
|
||||
QCOMPARE(c->eventCount(QEvent::LayoutRequest), 0);
|
||||
QCOMPARE(d->eventCount(QEvent::LayoutRequest), 1);
|
||||
|
||||
QCOMPARE(a->functionCount[SetGeometry], 1);
|
||||
QCOMPARE(alay->functionCount[SetGeometry], 1);
|
||||
|
||||
QCOMPARE(b->functionCount[SetGeometry], 1);
|
||||
QCOMPARE(c->functionCount[SetGeometry], 1);
|
||||
QCOMPARE(d->functionCount[SetGeometry], 1);
|
||||
// f actually got wider, need to rearrange its siblings
|
||||
QCOMPARE(blay->functionCount[SetGeometry], 1);
|
||||
QCOMPARE(clay->functionCount[SetGeometry], 0);
|
||||
QCOMPARE(dlay->functionCount[SetGeometry], 1);
|
||||
|
||||
QCOMPARE(e->functionCount[SetGeometry], 1);
|
||||
QCOMPARE(f->functionCount[SetGeometry], 0);
|
||||
QCOMPARE(g->functionCount[SetGeometry], 1);
|
||||
|
||||
}
|
||||
|
||||
QGraphicsLayout::setInstantInvalidatePropagation(false);
|
||||
}
|
||||
|
||||
class Layout : public QGraphicsLayout
|
||||
{
|
||||
public:
|
||||
Layout(QGraphicsLayoutItem *parentItem = 0) : QGraphicsLayout(parentItem) {}
|
||||
|
||||
void setGeometry(const QRectF &rect) override
|
||||
{
|
||||
QGraphicsLayout::setGeometry(rect);
|
||||
}
|
||||
|
||||
int count() const override
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
QGraphicsLayoutItem *itemAt(int index) const override
|
||||
{
|
||||
Q_UNUSED(index);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void removeAt(int index) override
|
||||
{
|
||||
Q_UNUSED(index);
|
||||
}
|
||||
|
||||
protected:
|
||||
QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const override
|
||||
{
|
||||
Q_UNUSED(constraint);
|
||||
Q_UNUSED(which);
|
||||
return QSizeF(100,100);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
void tst_QGraphicsLayout::constructors()
|
||||
{
|
||||
// Strange test, but see the fix that was with this submit
|
||||
QList<Layout *> layouts;
|
||||
for (int pass = 0; pass < 5; ++pass) {
|
||||
Layout *lay = new Layout();
|
||||
layouts << lay;
|
||||
qreal left, top, right, bottom;
|
||||
lay->getContentsMargins(&left, &top, &right, &bottom);
|
||||
// Test if the style defaults are sane (should always be ints)
|
||||
double intpart;
|
||||
QVERIFY(modf(left, &intpart) == 0.0);
|
||||
QVERIFY(modf(top, &intpart) == 0.0);
|
||||
QVERIFY(modf(right, &intpart) == 0.0);
|
||||
QVERIFY(modf(bottom, &intpart) == 0.0);
|
||||
|
||||
lay->setContentsMargins(1, 2, 4, 8);
|
||||
lay->getContentsMargins(&left, &top, &right, &bottom);
|
||||
|
||||
QCOMPARE(int(left), 1);
|
||||
QCOMPARE(int(top), 2);
|
||||
QCOMPARE(int(right), 4);
|
||||
QCOMPARE(int(bottom), 8);
|
||||
}
|
||||
|
||||
qDeleteAll(layouts);
|
||||
}
|
||||
|
||||
class AnimatedLayoutItem : public QGraphicsLayoutItem {
|
||||
public:
|
||||
AnimatedLayoutItem(QGraphicsRectItem *item)
|
||||
: QGraphicsLayoutItem()
|
||||
{
|
||||
setGraphicsItem(item);
|
||||
}
|
||||
|
||||
void setGeometry(const QRectF &geom) override;
|
||||
|
||||
QSizeF sizeHint(Qt::SizeHint which, const QSizeF & constraint = QSizeF() ) const override;
|
||||
|
||||
inline QGraphicsRectItem *rectItem() {
|
||||
return static_cast<QGraphicsRectItem *>(graphicsItem());
|
||||
}
|
||||
|
||||
QRectF m_geom;
|
||||
private:
|
||||
AnimatedLayoutItem() {}
|
||||
};
|
||||
|
||||
void AnimatedLayoutItem::setGeometry(const QRectF &geom)
|
||||
{
|
||||
QGraphicsLayoutItem::setGeometry(geom);
|
||||
}
|
||||
|
||||
QSizeF AnimatedLayoutItem::sizeHint(Qt::SizeHint which, const QSizeF & /* constraint */) const
|
||||
{
|
||||
switch (which) {
|
||||
case Qt::MinimumSize:
|
||||
return QSizeF(32,32);
|
||||
case Qt::PreferredSize:
|
||||
return QSizeF(160,90);
|
||||
case Qt::MaximumSize:
|
||||
return QSizeF(1000,1000);
|
||||
default:
|
||||
return QSizeF(300, 300);
|
||||
}
|
||||
}
|
||||
|
||||
class AnimatedLayout : public QObject, public QGraphicsLinearLayout {
|
||||
Q_OBJECT
|
||||
public:
|
||||
AnimatedLayout(QGraphicsWidget *widget) : QGraphicsLinearLayout(widget), m_timeline(500, this)
|
||||
{
|
||||
connect(&m_timeline, SIGNAL(valueChanged(qreal)), this, SLOT(valueChanged(qreal)));
|
||||
}
|
||||
|
||||
void setGeometry(const QRectF &geom) override
|
||||
{
|
||||
fromGeoms.clear();
|
||||
toGeoms.clear();
|
||||
for (int i = 0; i < count(); ++i) {
|
||||
fromGeoms << itemAt(i)->geometry();
|
||||
}
|
||||
|
||||
QGraphicsLinearLayout::setGeometry(geom);
|
||||
|
||||
for (int i = 0; i < count(); ++i) {
|
||||
toGeoms << itemAt(i)->geometry();
|
||||
}
|
||||
m_timeline.start();
|
||||
}
|
||||
|
||||
private slots:
|
||||
void valueChanged(qreal value) {
|
||||
for (int i = 0; i < fromGeoms.size(); ++i) {
|
||||
QGraphicsLayoutItem *li = itemAt(i);
|
||||
QRectF from = fromGeoms.at(i);
|
||||
QRectF to = toGeoms.at(i);
|
||||
|
||||
QRectF geom(from.topLeft() + (to.topLeft() - from.topLeft()) * value,
|
||||
from.size() + (to.size() - from.size()) * value);
|
||||
static_cast<QGraphicsRectItem*>(li->graphicsItem())->setRect(geom);
|
||||
}
|
||||
}
|
||||
private:
|
||||
QTimeLine m_timeline;
|
||||
QList<QRectF> fromGeoms;
|
||||
QList<QRectF> toGeoms;
|
||||
};
|
||||
|
||||
|
||||
void tst_QGraphicsLayout::alternativeLayoutItems()
|
||||
{
|
||||
QGraphicsScene scene;
|
||||
QGraphicsView view(&scene);
|
||||
|
||||
QGraphicsWidget *window = new QGraphicsWidget;
|
||||
scene.addItem(window);
|
||||
AnimatedLayout *lout = new AnimatedLayout(window);
|
||||
lout->setContentsMargins(0, 0, 0, 0);
|
||||
lout->setSpacing(0);
|
||||
|
||||
QGraphicsRectItem *item1 = new QGraphicsRectItem;
|
||||
AnimatedLayoutItem *li1 = new AnimatedLayoutItem(item1);
|
||||
lout->addItem(li1);
|
||||
|
||||
QGraphicsRectItem *item2 = new QGraphicsRectItem;
|
||||
AnimatedLayoutItem *li2 = new AnimatedLayoutItem(item2);
|
||||
lout->addItem(li2);
|
||||
|
||||
QGraphicsRectItem *item3 = new QGraphicsRectItem;
|
||||
AnimatedLayoutItem *li3 = new AnimatedLayoutItem(item3);
|
||||
lout->addItem(li3);
|
||||
|
||||
window->setLayout(lout);
|
||||
|
||||
window->setGeometry(0, 0, 99, 99);
|
||||
view.setSceneRect(QRectF(-10, -10, 110, 110));
|
||||
view.resize(150, 150);
|
||||
view.show();
|
||||
|
||||
QTRY_COMPARE(static_cast<QGraphicsRectItem*>(li1->graphicsItem())->rect(), QRectF( 0, 0, 33, 99));
|
||||
QTRY_COMPARE(static_cast<QGraphicsRectItem*>(li2->graphicsItem())->rect(), QRectF(33, 0, 33, 99));
|
||||
QTRY_COMPARE(static_cast<QGraphicsRectItem*>(li3->graphicsItem())->rect(), QRectF(66, 0, 33, 99));
|
||||
|
||||
lout->setOrientation(Qt::Vertical);
|
||||
|
||||
QTRY_COMPARE(static_cast<QGraphicsRectItem*>(li1->graphicsItem())->rect(), QRectF(0, 0, 99, 33));
|
||||
QTRY_COMPARE(static_cast<QGraphicsRectItem*>(li2->graphicsItem())->rect(), QRectF(0, 33, 99, 33));
|
||||
QTRY_COMPARE(static_cast<QGraphicsRectItem*>(li3->graphicsItem())->rect(), QRectF(0, 66, 99, 33));
|
||||
|
||||
}
|
||||
|
||||
class CustomLayoutItem : public QGraphicsLayoutItem {
|
||||
public:
|
||||
CustomLayoutItem(QSet<QGraphicsLayoutItem*> *destructedSet)
|
||||
: QGraphicsLayoutItem()
|
||||
{
|
||||
m_destructedSet = destructedSet;
|
||||
setOwnedByLayout(true);
|
||||
}
|
||||
|
||||
QSizeF sizeHint(Qt::SizeHint which, const QSizeF & constraint = QSizeF() ) const override;
|
||||
|
||||
~CustomLayoutItem() {
|
||||
m_destructedSet->insert(this);
|
||||
}
|
||||
private:
|
||||
QSet<QGraphicsLayoutItem*> *m_destructedSet;
|
||||
};
|
||||
|
||||
QSizeF CustomLayoutItem::sizeHint(Qt::SizeHint which, const QSizeF & /* constraint */) const
|
||||
{
|
||||
switch (which) {
|
||||
case Qt::MinimumSize:
|
||||
return QSizeF(32,32);
|
||||
case Qt::PreferredSize:
|
||||
return QSizeF(160,90);
|
||||
case Qt::MaximumSize:
|
||||
return QSizeF(1000,1000);
|
||||
default:
|
||||
return QSizeF(300, 300);
|
||||
}
|
||||
}
|
||||
|
||||
class CustomGraphicsWidget : public QGraphicsWidget {
|
||||
public:
|
||||
CustomGraphicsWidget(QSet<QGraphicsLayoutItem*> *destructedSet = 0)
|
||||
: QGraphicsWidget()
|
||||
{
|
||||
m_destructedSet = destructedSet;
|
||||
}
|
||||
|
||||
QSizeF sizeHint(Qt::SizeHint which, const QSizeF & constraint = QSizeF() ) const override;
|
||||
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget * = 0) override
|
||||
{
|
||||
const QRect r = option->rect.adjusted(0, 0, -1, -1);
|
||||
painter->drawLine(r.topLeft(), r.bottomRight());
|
||||
painter->drawLine(r.bottomLeft(), r.topRight());
|
||||
painter->drawRect(r);
|
||||
}
|
||||
|
||||
~CustomGraphicsWidget() {
|
||||
if (m_destructedSet)
|
||||
m_destructedSet->insert(this);
|
||||
}
|
||||
private:
|
||||
QSet<QGraphicsLayoutItem*> *m_destructedSet;
|
||||
};
|
||||
|
||||
QSizeF CustomGraphicsWidget::sizeHint(Qt::SizeHint which, const QSizeF & /* constraint */) const
|
||||
{
|
||||
switch (which) {
|
||||
case Qt::MinimumSize:
|
||||
return QSizeF(32,32);
|
||||
case Qt::PreferredSize:
|
||||
return QSizeF(160,90);
|
||||
case Qt::MaximumSize:
|
||||
return QSizeF(1000,1000);
|
||||
default:
|
||||
return QSizeF(300, 300);
|
||||
}
|
||||
}
|
||||
|
||||
static bool compareSets(const QSet<QGraphicsLayoutItem*> &actual, const QSet<QGraphicsLayoutItem*> &expected)
|
||||
{
|
||||
if (actual != expected) {
|
||||
qDebug() << "actual:" << actual << "expected:" << expected;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
class CustomLayout : public QGraphicsLayout
|
||||
{
|
||||
public :
|
||||
CustomLayout(QGraphicsLayoutItem *parent)
|
||||
: QGraphicsLayout(parent)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
~CustomLayout()
|
||||
{
|
||||
}
|
||||
|
||||
int count() const override
|
||||
{
|
||||
return items.size();
|
||||
}
|
||||
|
||||
QGraphicsLayoutItem* itemAt(int index) const override
|
||||
{
|
||||
return items.at(index);
|
||||
}
|
||||
|
||||
|
||||
void removeAt(int index) override
|
||||
{
|
||||
items.removeAt(index);
|
||||
}
|
||||
|
||||
void addItem(QGraphicsLayoutItem *item)
|
||||
{
|
||||
insertItem(items.size(), item);
|
||||
}
|
||||
|
||||
void insertItem(int index, QGraphicsLayoutItem *item)
|
||||
{
|
||||
index = qBound(0, index, items.size());
|
||||
|
||||
item->setParentLayoutItem(this);
|
||||
|
||||
QGraphicsWidget *widget = static_cast<QGraphicsWidget *>(item);
|
||||
updateParentWidget(widget);
|
||||
|
||||
|
||||
if (index == items.size()) {
|
||||
items.append(item);
|
||||
} else {
|
||||
items.insert(index, item);
|
||||
}
|
||||
|
||||
updateGeometry();
|
||||
activate();
|
||||
}
|
||||
|
||||
void updateParentWidget(QGraphicsWidget *item)
|
||||
{
|
||||
QGraphicsLayoutItem *parentItem = parentLayoutItem();
|
||||
while (parentItem && parentItem->isLayout()) {
|
||||
parentItem = parentItem->parentLayoutItem();
|
||||
}
|
||||
|
||||
if (parentItem) {
|
||||
item->setParentItem(static_cast<QGraphicsWidget*>(parentItem));
|
||||
}
|
||||
}
|
||||
|
||||
QSizeF sizeHint(Qt::SizeHint /* which */, const QSizeF & /* constraint */) const override
|
||||
{
|
||||
return QSizeF(50,50);
|
||||
}
|
||||
|
||||
QList<QGraphicsLayoutItem*> items;
|
||||
|
||||
};
|
||||
|
||||
void tst_QGraphicsLayout::ownership()
|
||||
{
|
||||
QGraphicsScene scene;
|
||||
QGraphicsView view(&scene);
|
||||
|
||||
{
|
||||
QGraphicsLinearLayout *lay = new QGraphicsLinearLayout;
|
||||
QSet<QGraphicsLayoutItem*> destructedSet;
|
||||
CustomLayoutItem *li1 = new CustomLayoutItem(&destructedSet);
|
||||
lay->addItem(li1);
|
||||
CustomLayoutItem *li2 = new CustomLayoutItem(&destructedSet);
|
||||
lay->addItem(li2);
|
||||
CustomLayoutItem *li3 = new CustomLayoutItem(&destructedSet);
|
||||
lay->addItem(li3);
|
||||
destructedSet.clear();
|
||||
|
||||
delete lay;
|
||||
QSet<QGraphicsLayoutItem*> expected;
|
||||
expected << li1 << li2 << li3;
|
||||
QVERIFY(compareSets(destructedSet, expected));
|
||||
}
|
||||
|
||||
{
|
||||
QGraphicsWidget *window = new QGraphicsWidget;
|
||||
QGraphicsLinearLayout *lay = new QGraphicsLinearLayout;
|
||||
QSet<QGraphicsLayoutItem*> destructedSet;
|
||||
CustomGraphicsWidget *li1 = new CustomGraphicsWidget(&destructedSet);
|
||||
lay->addItem(li1);
|
||||
CustomGraphicsWidget *li2 = new CustomGraphicsWidget(&destructedSet);
|
||||
lay->addItem(li2);
|
||||
CustomGraphicsWidget *li3 = new CustomGraphicsWidget(&destructedSet);
|
||||
lay->addItem(li3);
|
||||
window->setLayout(lay);
|
||||
scene.addItem(window);
|
||||
|
||||
destructedSet.clear();
|
||||
window->setLayout(0);
|
||||
QCOMPARE(destructedSet.size(), 0);
|
||||
delete window;
|
||||
}
|
||||
|
||||
{
|
||||
QGraphicsWidget *window = new QGraphicsWidget(0, Qt::Window);
|
||||
QGraphicsLinearLayout *lay = new QGraphicsLinearLayout;
|
||||
|
||||
CustomGraphicsWidget *li1 = new CustomGraphicsWidget;
|
||||
lay->addItem(li1);
|
||||
|
||||
QGraphicsLinearLayout *li2 = new QGraphicsLinearLayout;
|
||||
CustomGraphicsWidget *li2_1 = new CustomGraphicsWidget;
|
||||
li2->addItem(li2_1);
|
||||
CustomGraphicsWidget *li2_2 = new CustomGraphicsWidget;
|
||||
li2->addItem(li2_2);
|
||||
CustomGraphicsWidget *li2_3 = new CustomGraphicsWidget;
|
||||
li2->addItem(li2_3);
|
||||
lay->addItem(li2);
|
||||
|
||||
CustomGraphicsWidget *li3 = new CustomGraphicsWidget;
|
||||
lay->addItem(li3);
|
||||
|
||||
window->setLayout(lay);
|
||||
scene.addItem(window);
|
||||
view.resize(500, 200);
|
||||
view.show();
|
||||
|
||||
for (int i = li2->count(); i > 0; --i) {
|
||||
QCOMPARE(li2->count(), i);
|
||||
delete li2->itemAt(0);
|
||||
}
|
||||
|
||||
for (int i = lay->count(); i > 0; --i) {
|
||||
QCOMPARE(lay->count(), i);
|
||||
delete lay->itemAt(0);
|
||||
}
|
||||
|
||||
delete window;
|
||||
}
|
||||
|
||||
{
|
||||
QGraphicsWidget *top = new QGraphicsWidget;
|
||||
QGraphicsWidget *w = new QGraphicsWidget;
|
||||
QGraphicsWidget *w2 = new QGraphicsWidget;
|
||||
CustomLayout *layout = new CustomLayout(top);
|
||||
layout->addItem(w);
|
||||
layout->addItem(w2);
|
||||
top->setLayout(layout);
|
||||
delete top;
|
||||
//don't crash after that.
|
||||
}
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QGraphicsLayout)
|
||||
#include "tst_qgraphicslayout.moc"
|
Reference in New Issue
Block a user