diff options
Diffstat (limited to 'tests')
10 files changed, 814 insertions, 8 deletions
diff --git a/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp b/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp index e7c63d5..447385a 100644 --- a/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp +++ b/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp @@ -1091,6 +1091,9 @@ void tst_QGraphicsAnchorLayout::setSpacing() #ifdef Q_WS_MAC QTest::qWait(200); #endif + + // 21x21 + QCOMPARE(p->size(), QSizeF(41, 41)); QCOMPARE(a->geometry(), QRectF(0, 0, 20, 20)); QCOMPARE(b->geometry(), QRectF(21, 0, 20, 20)); QCOMPARE(c->geometry(), QRectF(0, 21, 41, 20)); diff --git a/tests/auto/qgraphicslayout/tst_qgraphicslayout.cpp b/tests/auto/qgraphicslayout/tst_qgraphicslayout.cpp index 979f03d..29ea074 100644 --- a/tests/auto/qgraphicslayout/tst_qgraphicslayout.cpp +++ b/tests/auto/qgraphicslayout/tst_qgraphicslayout.cpp @@ -62,6 +62,7 @@ private slots: void compressLayoutRequest(); void automaticReparenting(); void verifyActivate(); + void invalidate(); void constructors(); void alternativeLayoutItems(); void ownership(); @@ -95,6 +96,14 @@ void tst_QGraphicsLayout::sizeHints() } +enum FunctionType { + SetGeometry = 0, + Invalidate, + NumFunctionTypes +}; + + + class TestGraphicsWidget : public QGraphicsWidget { public: TestGraphicsWidget(QGraphicsWidget *parent = 0) : QGraphicsWidget(parent) @@ -108,9 +117,28 @@ public: 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) + { + QGraphicsWidget::setGeometry(rect); + ++(functionCount[SetGeometry]); + } + + void callUpdateGeometry() + { + // updateGeometry() is protected + QGraphicsWidget::updateGeometry(); + } + QMap<FunctionType, int> functionCount; private: QMap<int, int> m_eventCount; }; @@ -122,6 +150,8 @@ void tst_QGraphicsLayout::compressLayoutRequest() TestGraphicsWidget *tw = new TestGraphicsWidget(); scene.addItem(tw); view.show(); + + QTest::qWaitForWindowShown(&view); QGraphicsLinearLayout *lout = new QGraphicsLinearLayout(tw); for (int i = 0; i < 4; ++i) { QGraphicsWidget *gw = new QGraphicsWidget(tw); @@ -217,17 +247,27 @@ class TestLayout : public QGraphicsLinearLayout TestLayout(QGraphicsLayoutItem *parent = 0) : QGraphicsLinearLayout(parent) { - m_count = 0; + setContentsMargins(0,0,0,0); + setSpacing(0); } - void setGeometry(const QRectF &rect) { - - ++m_count; + void setGeometry(const QRectF &rect) + { + ++(functionCount[SetGeometry]); QGraphicsLinearLayout::setGeometry(rect); } + void invalidate() + { + ++(functionCount[Invalidate]); + QGraphicsLinearLayout::invalidate(); + } + + void clearCounters() { + functionCount.clear(); + } - int m_count; + QMap<FunctionType, int> functionCount; }; void tst_QGraphicsLayout::verifyActivate() @@ -242,13 +282,278 @@ void tst_QGraphicsLayout::verifyActivate() lout->addItem(w); window->setLayout(lout); - QCOMPARE(lout->m_count, 0); + QCOMPARE(lout->functionCount[SetGeometry], 0); window->setVisible(false); - QCOMPARE(lout->m_count, 0); + QCOMPARE(lout->functionCount[SetGeometry], 0); window->setVisible(true); // on polish or the first time a widget is shown, the widget is resized. - QCOMPARE(lout->m_count, 1); + QCOMPARE(lout->functionCount[SetGeometry], 1); + +} + +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 diff --git a/tests/auto/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp b/tests/auto/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp index 62ba1b4..8f8ac67 100644 --- a/tests/auto/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp +++ b/tests/auto/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp @@ -94,6 +94,7 @@ private slots: void itemSpacing(); void setStretchFactor_data(); void setStretchFactor(); + void testStretch(); void defaultStretchFactors_data(); void defaultStretchFactors(); void sizeHint_data(); @@ -667,6 +668,10 @@ void tst_QGraphicsLinearLayout::invalidate() layout.setContentsMargins(0, 0, 0, 0); view.show(); widget->show(); + //QTest::qWait(1000); + QTest::qWaitForWindowShown(&view); + qApp->processEvents(); + layout.layoutRequest = 0; layout.setContentsMargins(1, 2, 3, 4); QApplication::sendPostedEvents(0, 0); @@ -1130,6 +1135,41 @@ void tst_QGraphicsLinearLayout::setStretchFactor() delete widget; } +void tst_QGraphicsLinearLayout::testStretch() +{ + QGraphicsScene scene; + QGraphicsView *view = new QGraphicsView(&scene); + QGraphicsWidget *form = new QGraphicsWidget(0, Qt::Window); + + scene.addItem(form); + form->setMinimumSize(600, 600); + form->setMaximumSize(600, 600); + QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(Qt::Horizontal, form); + QGraphicsWidget *w1 = new RectWidget; + w1->setPreferredSize(100,100); + w1->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + QGraphicsWidget *w2 = new RectWidget; + w2->setPreferredSize(200,200); + w2->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + layout->setSpacing(0); + layout->setContentsMargins(0, 0, 0, 0); + layout->addItem(w1); + layout->addStretch(2); + layout->addItem(w2); + QCOMPARE(layout->count(), 2); + QVERIFY(layout->itemAt(0) == w1); + QVERIFY(layout->itemAt(1) == w2); + layout->activate(); + + //view->setSceneRect(-50, -50, 800, 800); + //view->show(); + //QTest::qWaitForWindowShown(view); + //QTest::qWait(5000); + QCOMPARE(form->geometry().size(), QSizeF(600,600)); + QCOMPARE(w1->geometry(), QRectF(0, 0, 100, 100)); + QCOMPARE(w2->geometry(), QRectF(400, 0, 200, 200)); +} + void tst_QGraphicsLinearLayout::defaultStretchFactors_data() { QTest::addColumn<Qt::Orientation>("orientation"); diff --git a/tests/benchmarks/gui/graphicsview/graphicsview.pro b/tests/benchmarks/gui/graphicsview/graphicsview.pro index e4fed19..1509466 100644 --- a/tests/benchmarks/gui/graphicsview/graphicsview.pro +++ b/tests/benchmarks/gui/graphicsview/graphicsview.pro @@ -3,6 +3,7 @@ SUBDIRS = \ functional \ qgraphicsanchorlayout \ qgraphicsitem \ + qgraphicslayout \ qgraphicsscene \ qgraphicsview \ qgraphicswidget diff --git a/tests/benchmarks/gui/graphicsview/qgraphicslayout/qgraphicslayout.pro b/tests/benchmarks/gui/graphicsview/qgraphicslayout/qgraphicslayout.pro new file mode 100644 index 0000000..19e2979 --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/qgraphicslayout/qgraphicslayout.pro @@ -0,0 +1,6 @@ +load(qttest_p4) +TEMPLATE = app +TARGET = tst_bench_qgraphicslayout + +SOURCES += tst_qgraphicslayout.cpp + diff --git a/tests/benchmarks/gui/graphicsview/qgraphicslayout/tst_qgraphicslayout.cpp b/tests/benchmarks/gui/graphicsview/qgraphicslayout/tst_qgraphicslayout.cpp new file mode 100644 index 0000000..4bdcfb3 --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/qgraphicslayout/tst_qgraphicslayout.cpp @@ -0,0 +1,153 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/QtTest> +#include <QtGui/qgraphicslayout.h> +#include <QtGui/qgraphicslinearlayout.h> +#include <QtGui/qgraphicswidget.h> +#include <QtGui/qgraphicsview.h> + +class tst_QGraphicsLayout : public QObject +{ + Q_OBJECT +public: + tst_QGraphicsLayout() {} + ~tst_QGraphicsLayout() {} + +private slots: + void invalidate(); +}; + + +class RectWidget : public QGraphicsWidget +{ +public: + RectWidget(QGraphicsItem *parent = 0, Qt::WindowFlags wFlags = 0) : QGraphicsWidget(parent, wFlags), setGeometryCalls(0) {} + + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) + { + Q_UNUSED(option); + Q_UNUSED(widget); + painter->drawRoundRect(rect()); + painter->drawLine(rect().topLeft(), rect().bottomRight()); + painter->drawLine(rect().bottomLeft(), rect().topRight()); + } + + void setGeometry(const QRectF &rect) + { + //qDebug() << "setGeometry():" << this->data(0).toString(); + setGeometryCalls->insert(this, rect); + QGraphicsWidget::setGeometry(rect); + } + + void callUpdateGeometry() { + QGraphicsWidget::updateGeometry(); + } + + QMap<RectWidget*, QRectF> *setGeometryCalls; +}; + +/** + * Test to see how much time is needed to resize all widgets in a + * layout-widget-layout-widget-.... hierarchy from the point where a + * leaf widget changes its size hint. (updateGeometry() is called). + * + * If you run the test for 4.7 you'll get some really high numbers, but + * that's because they also include painting (and possible processing of + * some other events). + */ +void tst_QGraphicsLayout::invalidate() +{ + QGraphicsLayout::setInstantInvalidatePropagation(true); + QGraphicsScene scene; + QGraphicsView *view = new QGraphicsView(&scene); + QMap<RectWidget*, QRectF> setGeometryCalls; + + RectWidget *window = new RectWidget(0, Qt::Window); + window->setGeometryCalls = &setGeometryCalls; + window->setData(0, QString(QChar('a'))); + + scene.addItem(window); + RectWidget *leaf = 0; + const int depth = 100; + RectWidget *parent = window; + for (int i = 1; i < depth; ++i) { + QGraphicsLinearLayout *l = new QGraphicsLinearLayout(parent); + l->setContentsMargins(0,0,0,0); + RectWidget *child = new RectWidget; + child->setData(0, QString(QChar('a' + i))); + child->setGeometryCalls = &setGeometryCalls; + l->addItem(child); + parent = child; + } + leaf = parent; + leaf->setMinimumSize(QSizeF(1,1)); + + view->show(); + + QTest::qWaitForWindowShown(view); + + // ...then measure... + + int pass = 1; + + // should be as small as possible, to reduce overhead of painting + QSizeF size(1, 1); + setGeometryCalls.clear(); + QBENCHMARK { + leaf->setMinimumSize(size); + leaf->setMaximumSize(size); + while (setGeometryCalls.count() < depth) { + QApplication::sendPostedEvents(); + } + // force a resize on each widget, this will ensure + // that each iteration will resize all 50 widgets + int w = int(size.width()); + w^=2; + size.setWidth(w); + } + delete view; + QGraphicsLayout::setInstantInvalidatePropagation(false); +} + +QTEST_MAIN(tst_QGraphicsLayout) + +#include "tst_qgraphicslayout.moc" diff --git a/tests/manual/qgraphicslayout/flicker/flicker.pro b/tests/manual/qgraphicslayout/flicker/flicker.pro new file mode 100644 index 0000000..323a30f --- /dev/null +++ b/tests/manual/qgraphicslayout/flicker/flicker.pro @@ -0,0 +1,8 @@ +TEMPLATE = app +TARGET = +DEPENDPATH += . +INCLUDEPATH += . + +# Input +HEADERS += window.h +SOURCES += main.cpp window.cpp diff --git a/tests/manual/qgraphicslayout/flicker/main.cpp b/tests/manual/qgraphicslayout/flicker/main.cpp new file mode 100644 index 0000000..838d45f --- /dev/null +++ b/tests/manual/qgraphicslayout/flicker/main.cpp @@ -0,0 +1,15 @@ +#include <QtGui> +#include <windows.h> +#include "window.h" + +int main(int argc, char **argv) +{ + QApplication app(argc, argv); + Window *window = new Window(); + window->resize(800, 600); + + window->show(); + + return app.exec(); + +} diff --git a/tests/manual/qgraphicslayout/flicker/window.cpp b/tests/manual/qgraphicslayout/flicker/window.cpp new file mode 100644 index 0000000..d193ad1 --- /dev/null +++ b/tests/manual/qgraphicslayout/flicker/window.cpp @@ -0,0 +1,32 @@ +#include "window.h" + +void SlowWidget::setGeometry(const QRectF &rect) +{ + bool reiterate = false; + Statistics &stats = *m_stats; + if (stats.relayoutClicked) { + ++(stats.setGeometryTracker[this]); + ++stats.setGeometryCount; + qDebug() << "setGeometryCount:" << stats.setGeometryCount; + if (stats.setGeometryTracker.count() == m_window->m_depthSpinBox->value()) { + ++stats.currentBenchmarkIteration; + qDebug() << "currentBenchmarkIteration:" << stats.currentBenchmarkIteration; + if (stats.currentBenchmarkIteration == m_window->m_benchmarkIterationsSpinBox->value()) { + if (stats.output) + stats.output->setText(tr("DONE. Elapsed: %1, setGeometryCount: %2").arg(stats.time.elapsed()).arg(stats.setGeometryCount)); + } else { + reiterate = true; + } + stats.setGeometryTracker.clear(); + + } + } + + QGraphicsWidget::setGeometry(rect); + + if (reiterate) { + m_window->doAgain(); + //QTimer::singleShot(0, m_window, SLOT(doAgain())); + } +} + diff --git a/tests/manual/qgraphicslayout/flicker/window.h b/tests/manual/qgraphicslayout/flicker/window.h new file mode 100644 index 0000000..df1fc82 --- /dev/null +++ b/tests/manual/qgraphicslayout/flicker/window.h @@ -0,0 +1,243 @@ +#ifndef WINDOW_H +#define WINDOW_H + + +#include <QtGui> + +static void qSleep(int msec) +{ + + struct Thread : public QThread + { + static void wait(int msec) + { + QThread::msleep(msec); + } + }; + Thread::wait(msec); +} + +struct Statistics { + Statistics() : output(0), + setGeometryCount(0), currentBenchmarkIteration(0), relayoutClicked(false), sleepMsecs(0) + { + } + QMap<QGraphicsWidget*, int> setGeometryTracker; + QTime time; + int setGeometryCount; + int sleepMsecs; + QLabel *output; + void sleep() + { + qSleep(sleepMsecs); + } + int currentBenchmarkIteration; + bool relayoutClicked; + +}; + + +class Window; + +class SlowWidget : public QGraphicsWidget { +public: + SlowWidget(QGraphicsWidget *w = 0, Qt::WindowFlags wFlags = 0) : QGraphicsWidget(w, wFlags) + { + m_window = 0; + } + + void setStats(Statistics *stats) + { + m_stats = stats; + } + + void setWindow(Window *window) + { + m_window = window; + } + + void setGeometry(const QRectF &rect); + + bool event(QEvent *e) + { + if (e->type() == QEvent::LayoutRequest) { + if (m_stats->sleepMsecs > 0) { + m_stats->sleep(); + qDebug("sleep %d ms\n", m_stats->sleepMsecs); + } + } + return QGraphicsWidget::event(e); + } + + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) + { + Q_UNUSED(option); + Q_UNUSED(widget); + painter->setBrush(m_brush); + painter->drawRoundRect(rect()); + painter->drawLine(rect().topLeft(), rect().bottomRight()); + painter->drawLine(rect().bottomLeft(), rect().topRight()); + } + + void setBrush(const QBrush &brush) + { + m_brush = brush; + } +private: + QBrush m_brush; + Statistics *m_stats; + Window *m_window; +}; + +class Window : public QWidget { + Q_OBJECT +public: + Window() : QWidget() + { + QGraphicsView *m_view = new QGraphicsView(&scene); + + m_window = 0; + m_leaf = 0; + + m_button = new QPushButton(tr("Relayout")); + m_button->setObjectName("button"); + + m_sleepLabel = new QLabel(tr("Sleep:")); + m_sleepSpinBox = new QSpinBox; + m_sleepSpinBox->setRange(0, 1000); + m_sleepSpinBox->setSingleStep(10); + + m_depthLabel = new QLabel(tr("Depth:")); + m_depthSpinBox = new QSpinBox; + m_depthSpinBox->setObjectName("depthSpinBox"); + m_depthSpinBox->setRange(1, 200); + m_depthSpinBox->setSingleStep(5); + + m_benchmarkIterationsLabel = new QLabel(tr("Benchmark iterations")); + m_benchmarkIterationsSpinBox = new QSpinBox; + m_benchmarkIterationsSpinBox->setObjectName("benchmarkIterationsSpinBox"); + m_benchmarkIterationsSpinBox->setRange(1, 1000); + m_benchmarkIterationsSpinBox->setValue(41); + m_benchmarkIterationsSpinBox->setSingleStep(10); + + m_instantCheckBox = new QCheckBox(tr("Instant propagation")); + m_instantCheckBox->setObjectName("instantPropagationCheckbox"); + QGraphicsLayout::setInstantInvalidatePropagation(true); + m_instantCheckBox->setChecked(QGraphicsLayout::instantInvalidatePropagation()); + + m_resultLabel = new QLabel(tr("Press relayout to start test")); + + QHBoxLayout *hbox = new QHBoxLayout; + hbox->addWidget(m_sleepLabel); + hbox->addWidget(m_sleepSpinBox); + hbox->addWidget(m_depthLabel); + hbox->addWidget(m_depthSpinBox); + hbox->addWidget(m_benchmarkIterationsLabel); + hbox->addWidget(m_benchmarkIterationsSpinBox); + hbox->addWidget(m_instantCheckBox); + hbox->addWidget(m_resultLabel); + hbox->addStretch(); + hbox->addWidget(m_button); + + QVBoxLayout *vbox = new QVBoxLayout; + vbox->addWidget(m_view); + vbox->addLayout(hbox); + setLayout(vbox); + + metaObject()->connectSlotsByName(this); + + m_depthSpinBox->setValue(20); // triggers purposedly on_depthSpinBox_valueChanged + } + +private slots: + void on_depthSpinBox_valueChanged(int value) + { + m_stats.relayoutClicked = false; + if (m_window) { + QApplication::processEvents(); + delete m_window; + } + m_window = new SlowWidget(0, Qt::Window); + m_window->setStats(&m_stats); + m_window->setWindow(this); + QColor col(Qt::black); + m_window->setBrush(col); + scene.addItem(m_window); + m_leaf = 0; + const int depth = value; + SlowWidget *parent = m_window; + for (int i = 1; i < depth; ++i) { + QGraphicsLinearLayout *l = new QGraphicsLinearLayout(parent); + l->setContentsMargins(2,2,2,2); + SlowWidget *child = new SlowWidget; + QColor col; + col.setHsl(0, 0, 255*i/(depth - 1)); + child->setBrush(col); + child->setStats(&m_stats); + child->setWindow(this); + l->addItem(child); + parent = child; + } + m_leaf = parent; + } + + void on_button_clicked(bool /*check = false*/) + { + m_stats.relayoutClicked = true; + if (m_leaf) { + QSizeF sz = m_leaf->size(); + int w = int(sz.width()); + w^=16; + sz = QSizeF(w,w); + m_stats.output = m_resultLabel; + m_stats.output->setText(QString("wait...")); + m_stats.setGeometryCount = 0; + m_stats.setGeometryTracker.clear(); + m_stats.sleepMsecs = m_sleepSpinBox->value(); + m_stats.time.start(); + m_stats.currentBenchmarkIteration = 0; + m_leaf->setMinimumSize(sz); + m_leaf->setMaximumSize(sz); + } + } + + void on_instantPropagationCheckbox_toggled(bool checked) + { + QGraphicsLayout::setInstantInvalidatePropagation(checked); + } + +public slots: + void doAgain() + { + if (m_leaf) { + QSizeF sz = m_leaf->size(); + int w = int(sz.width()); + w^=16; + sz = QSizeF(w,w); + m_leaf->setMinimumSize(sz); + m_leaf->setMaximumSize(sz); + } + } + +private: +public: + QGraphicsScene scene; + QGraphicsView *m_view; + QPushButton *m_button; + QLabel *m_sleepLabel; + QSpinBox *m_sleepSpinBox; + QLabel *m_depthLabel; + QSpinBox *m_depthSpinBox; + QLabel *m_benchmarkIterationsLabel; + QSpinBox *m_benchmarkIterationsSpinBox; + QCheckBox *m_instantCheckBox; + QLabel *m_resultLabel; + QGraphicsWidget *m_leaf; + SlowWidget *m_window; + Statistics m_stats; + + +}; + + +#endif //WINDOW_H |