Avoid flicker when invalidate is propagated in a widget/layout hierarchy
* Do not call invalidate from activateRecursive(). This resulted in that a layout was invalidated as many times as there were items in the layout. * Several improvements. Do not call resize(size()) too often. Calling resize() from the widgetEvent() is not very nice though... * Remove commented out code * make sure layout is activated even if the widget does not change size * activate the layout if the resize is same as size() * In order to not break existing apps, make this an opt-in feature with QGraphicsLayout::setInstantInvalidatePropagation(true); Reviewed-by: Frederik Gladhorn Reviewed-by: John Tapsell
This commit is contained in:
parent
1ce725cb60
commit
913ff73200
@ -269,12 +269,20 @@ void QGraphicsLayout::activate()
|
|||||||
return;
|
return;
|
||||||
Q_ASSERT(!parentItem->isLayout());
|
Q_ASSERT(!parentItem->isLayout());
|
||||||
|
|
||||||
setGeometry(parentItem->contentsRect()); // relayout children
|
if (QGraphicsLayout::instantInvalidatePropagation()) {
|
||||||
|
QGraphicsWidget *parentWidget = static_cast<QGraphicsWidget*>(parentItem);
|
||||||
|
if (!parentWidget->parentLayoutItem()) {
|
||||||
|
// we've reached the topmost widget, resize it
|
||||||
|
bool wasResized = parentWidget->testAttribute(Qt::WA_Resized);
|
||||||
|
parentWidget->resize(parentWidget->size());
|
||||||
|
parentWidget->setAttribute(Qt::WA_Resized, wasResized);
|
||||||
|
}
|
||||||
|
|
||||||
// ### bug, should be parentItem ?
|
setGeometry(parentItem->contentsRect()); // relayout children
|
||||||
parentLayoutItem()->updateGeometry(); // bubble up; will set activated to false
|
} else {
|
||||||
// ### too many resizes? maybe we should walk up the chain to the
|
setGeometry(parentItem->contentsRect()); // relayout children
|
||||||
// ### top-level layouted layoutItem and call activate there.
|
parentLayoutItem()->updateGeometry();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -300,32 +308,36 @@ bool QGraphicsLayout::isActivated() const
|
|||||||
*/
|
*/
|
||||||
void QGraphicsLayout::invalidate()
|
void QGraphicsLayout::invalidate()
|
||||||
{
|
{
|
||||||
// only mark layouts as invalid (activated = false) if we can post a LayoutRequest event.
|
if (QGraphicsLayout::instantInvalidatePropagation()) {
|
||||||
QGraphicsLayoutItem *layoutItem = this;
|
updateGeometry();
|
||||||
while (layoutItem && layoutItem->isLayout()) {
|
} else {
|
||||||
// we could call updateGeometry(), but what if that method
|
// only mark layouts as invalid (activated = false) if we can post a LayoutRequest event.
|
||||||
// does not call the base implementation? In addition, updateGeometry()
|
QGraphicsLayoutItem *layoutItem = this;
|
||||||
// does more than we need.
|
while (layoutItem && layoutItem->isLayout()) {
|
||||||
layoutItem->d_func()->sizeHintCacheDirty = true;
|
// we could call updateGeometry(), but what if that method
|
||||||
layoutItem->d_func()->sizeHintWithConstraintCacheDirty = true;
|
// does not call the base implementation? In addition, updateGeometry()
|
||||||
layoutItem = layoutItem->parentLayoutItem();
|
// does more than we need.
|
||||||
}
|
layoutItem->d_func()->sizeHintCacheDirty = true;
|
||||||
if (layoutItem) {
|
layoutItem->d_func()->sizeHintWithConstraintCacheDirty = true;
|
||||||
layoutItem->d_func()->sizeHintCacheDirty = true;
|
|
||||||
layoutItem->d_func()->sizeHintWithConstraintCacheDirty = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool postIt = layoutItem ? !layoutItem->isLayout() : false;
|
|
||||||
if (postIt) {
|
|
||||||
layoutItem = this;
|
|
||||||
while (layoutItem && layoutItem->isLayout()
|
|
||||||
&& static_cast<QGraphicsLayout*>(layoutItem)->d_func()->activated) {
|
|
||||||
static_cast<QGraphicsLayout*>(layoutItem)->d_func()->activated = false;
|
|
||||||
layoutItem = layoutItem->parentLayoutItem();
|
layoutItem = layoutItem->parentLayoutItem();
|
||||||
}
|
}
|
||||||
if (layoutItem && !layoutItem->isLayout()) {
|
if (layoutItem) {
|
||||||
// If a layout has a parent that is not a layout it must be a QGraphicsWidget.
|
layoutItem->d_func()->sizeHintCacheDirty = true;
|
||||||
QApplication::postEvent(static_cast<QGraphicsWidget *>(layoutItem), new QEvent(QEvent::LayoutRequest));
|
layoutItem->d_func()->sizeHintWithConstraintCacheDirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool postIt = layoutItem ? !layoutItem->isLayout() : false;
|
||||||
|
if (postIt) {
|
||||||
|
layoutItem = this;
|
||||||
|
while (layoutItem && layoutItem->isLayout()
|
||||||
|
&& static_cast<QGraphicsLayout*>(layoutItem)->d_func()->activated) {
|
||||||
|
static_cast<QGraphicsLayout*>(layoutItem)->d_func()->activated = false;
|
||||||
|
layoutItem = layoutItem->parentLayoutItem();
|
||||||
|
}
|
||||||
|
if (layoutItem && !layoutItem->isLayout()) {
|
||||||
|
// If a layout has a parent that is not a layout it must be a QGraphicsWidget.
|
||||||
|
QApplication::postEvent(static_cast<QGraphicsWidget *>(layoutItem), new QEvent(QEvent::LayoutRequest));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -335,12 +347,27 @@ void QGraphicsLayout::invalidate()
|
|||||||
*/
|
*/
|
||||||
void QGraphicsLayout::updateGeometry()
|
void QGraphicsLayout::updateGeometry()
|
||||||
{
|
{
|
||||||
QGraphicsLayoutItem::updateGeometry();
|
Q_D(QGraphicsLayout);
|
||||||
if (QGraphicsLayoutItem *parentItem = parentLayoutItem()) {
|
if (QGraphicsLayout::instantInvalidatePropagation()) {
|
||||||
if (parentItem->isLayout()) {
|
d->activated = false;
|
||||||
|
QGraphicsLayoutItem::updateGeometry();
|
||||||
|
|
||||||
|
QGraphicsLayoutItem *parentItem = parentLayoutItem();
|
||||||
|
if (!parentItem)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (parentItem->isLayout())
|
||||||
|
static_cast<QGraphicsLayout *>(parentItem)->invalidate();
|
||||||
|
else
|
||||||
parentItem->updateGeometry();
|
parentItem->updateGeometry();
|
||||||
} else {
|
} else {
|
||||||
invalidate();
|
QGraphicsLayoutItem::updateGeometry();
|
||||||
|
if (QGraphicsLayoutItem *parentItem = parentLayoutItem()) {
|
||||||
|
if (parentItem->isLayout()) {
|
||||||
|
parentItem->updateGeometry();
|
||||||
|
} else {
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -446,6 +473,50 @@ void QGraphicsLayout::addChildLayoutItem(QGraphicsLayoutItem *layoutItem)
|
|||||||
d->addChildLayoutItem(layoutItem);
|
d->addChildLayoutItem(layoutItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool g_instantInvalidatePropagation = false;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\internal
|
||||||
|
\since 4.8
|
||||||
|
\see instantInvalidatePropagation
|
||||||
|
|
||||||
|
Calling this function with \a enable set to true will enable a feature that
|
||||||
|
makes propagation of invalidation up to ancestor layout items to be done in
|
||||||
|
one go. It will propagate up the parentLayoutItem() hierarchy until it has
|
||||||
|
reached the root. If the root item is a QGraphicsWidget, it will *post* a
|
||||||
|
layout request to it. When the layout request is consumed it will traverse
|
||||||
|
down the hierarchy of layouts and widgets and activate all layouts that is
|
||||||
|
invalid (not activated). This is the recommended behaviour.
|
||||||
|
|
||||||
|
If not set it will also propagate up the parentLayoutItem() hierarchy, but
|
||||||
|
it will stop at the \i first \i widget it encounters, and post a layout
|
||||||
|
request to the widget. When the layout request is consumed, this might
|
||||||
|
cause it to continue propagation up to the parentLayoutItem() of the
|
||||||
|
widget. It will continue in this fashion until it has reached a widget with
|
||||||
|
no parentLayoutItem(). This strategy might cause drawing artifacts, since
|
||||||
|
it is not done in one go, and the consumption of layout requests might be
|
||||||
|
interleaved by consumption of paint events, which might cause significant
|
||||||
|
flicker.
|
||||||
|
Note, this is not the recommended behavior, but for compatibility reasons
|
||||||
|
this is the default behaviour.
|
||||||
|
*/
|
||||||
|
void QGraphicsLayout::setInstantInvalidatePropagation(bool enable)
|
||||||
|
{
|
||||||
|
g_instantInvalidatePropagation = enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\internal
|
||||||
|
\since 4.8
|
||||||
|
\see setInstantInvalidatePropagation
|
||||||
|
|
||||||
|
returns true if the complete widget/layout hierarchy is rearranged in one go.
|
||||||
|
*/
|
||||||
|
bool QGraphicsLayout::instantInvalidatePropagation()
|
||||||
|
{
|
||||||
|
return g_instantInvalidatePropagation;
|
||||||
|
}
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
#endif //QT_NO_GRAPHICSVIEW
|
#endif //QT_NO_GRAPHICSVIEW
|
||||||
|
@ -76,6 +76,8 @@ public:
|
|||||||
virtual QGraphicsLayoutItem *itemAt(int i) const = 0;
|
virtual QGraphicsLayoutItem *itemAt(int i) const = 0;
|
||||||
virtual void removeAt(int index) = 0;
|
virtual void removeAt(int index) = 0;
|
||||||
|
|
||||||
|
static void setInstantInvalidatePropagation(bool enable);
|
||||||
|
static bool instantInvalidatePropagation();
|
||||||
protected:
|
protected:
|
||||||
QGraphicsLayout(QGraphicsLayoutPrivate &, QGraphicsLayoutItem *);
|
QGraphicsLayout(QGraphicsLayoutPrivate &, QGraphicsLayoutItem *);
|
||||||
void addChildLayoutItem(QGraphicsLayoutItem *layoutItem);
|
void addChildLayoutItem(QGraphicsLayoutItem *layoutItem);
|
||||||
|
@ -180,9 +180,14 @@ void QGraphicsLayoutPrivate::activateRecursive(QGraphicsLayoutItem *item)
|
|||||||
{
|
{
|
||||||
if (item->isLayout()) {
|
if (item->isLayout()) {
|
||||||
QGraphicsLayout *layout = static_cast<QGraphicsLayout *>(item);
|
QGraphicsLayout *layout = static_cast<QGraphicsLayout *>(item);
|
||||||
if (layout->d_func()->activated)
|
if (layout->d_func()->activated) {
|
||||||
layout->invalidate();
|
if (QGraphicsLayout::instantInvalidatePropagation()) {
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
layout->invalidate(); // ### LOOKS SUSPICIOUSLY WRONG!!???
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = layout->count() - 1; i >= 0; --i) {
|
for (int i = layout->count() - 1; i >= 0; --i) {
|
||||||
QGraphicsLayoutItem *childItem = layout->itemAt(i);
|
QGraphicsLayoutItem *childItem = layout->itemAt(i);
|
||||||
if (childItem)
|
if (childItem)
|
||||||
|
@ -275,17 +275,16 @@ void QGraphicsLinearLayout::insertItem(int index, QGraphicsLayoutItem *item)
|
|||||||
qWarning("QGraphicsLinearLayout::insertItem: cannot insert itself");
|
qWarning("QGraphicsLinearLayout::insertItem: cannot insert itself");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Q_ASSERT(item);
|
|
||||||
|
|
||||||
//the order of the following instructions is very important because
|
|
||||||
//invalidating the layout before adding the child item will make the layout happen
|
|
||||||
//before we try to paint the item
|
|
||||||
invalidate();
|
|
||||||
d->addChildLayoutItem(item);
|
d->addChildLayoutItem(item);
|
||||||
|
|
||||||
d->fixIndex(&index);
|
d->fixIndex(&index);
|
||||||
d->engine.insertRow(index, d->orientation);
|
d->engine.insertRow(index, d->orientation);
|
||||||
new QGridLayoutItem(&d->engine, item, d->gridRow(index), d->gridColumn(index), 1, 1, 0, index);
|
new QGridLayoutItem(&d->engine, item, d->gridRow(index), d->gridColumn(index), 1, 1, 0, index);
|
||||||
|
//the order of the following instructions is very important because
|
||||||
|
//invalidating the layout before adding the child item will make the layout happen
|
||||||
|
//before we try to paint the item
|
||||||
|
invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -354,8 +354,10 @@ void QGraphicsWidget::setGeometry(const QRectF &rect)
|
|||||||
newGeom = rect;
|
newGeom = rect;
|
||||||
newGeom.setSize(rect.size().expandedTo(effectiveSizeHint(Qt::MinimumSize))
|
newGeom.setSize(rect.size().expandedTo(effectiveSizeHint(Qt::MinimumSize))
|
||||||
.boundedTo(effectiveSizeHint(Qt::MaximumSize)));
|
.boundedTo(effectiveSizeHint(Qt::MaximumSize)));
|
||||||
if (newGeom == d->geom)
|
|
||||||
return;
|
if (newGeom == d->geom) {
|
||||||
|
goto relayoutChildrenAndReturn;
|
||||||
|
}
|
||||||
|
|
||||||
// setPos triggers ItemPositionChange, which can adjust position
|
// setPos triggers ItemPositionChange, which can adjust position
|
||||||
wd->inSetGeometry = 1;
|
wd->inSetGeometry = 1;
|
||||||
@ -363,8 +365,9 @@ void QGraphicsWidget::setGeometry(const QRectF &rect)
|
|||||||
wd->inSetGeometry = 0;
|
wd->inSetGeometry = 0;
|
||||||
newGeom.moveTopLeft(pos());
|
newGeom.moveTopLeft(pos());
|
||||||
|
|
||||||
if (newGeom == d->geom)
|
if (newGeom == d->geom) {
|
||||||
return;
|
goto relayoutChildrenAndReturn;
|
||||||
|
}
|
||||||
|
|
||||||
// Update and prepare to change the geometry (remove from index) if the size has changed.
|
// Update and prepare to change the geometry (remove from index) if the size has changed.
|
||||||
if (wd->scene) {
|
if (wd->scene) {
|
||||||
@ -375,35 +378,54 @@ void QGraphicsWidget::setGeometry(const QRectF &rect)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update the layout item geometry
|
// Update the layout item geometry
|
||||||
bool moved = oldPos != pos();
|
{
|
||||||
if (moved) {
|
bool moved = oldPos != pos();
|
||||||
// Send move event.
|
if (moved) {
|
||||||
QGraphicsSceneMoveEvent event;
|
// Send move event.
|
||||||
event.setOldPos(oldPos);
|
QGraphicsSceneMoveEvent event;
|
||||||
event.setNewPos(pos());
|
event.setOldPos(oldPos);
|
||||||
QApplication::sendEvent(this, &event);
|
event.setNewPos(pos());
|
||||||
if (wd->inSetPos) {
|
QApplication::sendEvent(this, &event);
|
||||||
//set the new pos
|
if (wd->inSetPos) {
|
||||||
d->geom.moveTopLeft(pos());
|
//set the new pos
|
||||||
emit geometryChanged();
|
d->geom.moveTopLeft(pos());
|
||||||
return;
|
emit geometryChanged();
|
||||||
|
goto relayoutChildrenAndReturn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
QSizeF oldSize = size();
|
||||||
|
QGraphicsLayoutItem::setGeometry(newGeom);
|
||||||
|
// Send resize event
|
||||||
|
bool resized = newGeom.size() != oldSize;
|
||||||
|
if (resized) {
|
||||||
|
QGraphicsSceneResizeEvent re;
|
||||||
|
re.setOldSize(oldSize);
|
||||||
|
re.setNewSize(newGeom.size());
|
||||||
|
if (oldSize.width() != newGeom.size().width())
|
||||||
|
emit widthChanged();
|
||||||
|
if (oldSize.height() != newGeom.size().height())
|
||||||
|
emit heightChanged();
|
||||||
|
QGraphicsLayout *lay = wd->layout;
|
||||||
|
if (QGraphicsLayout::instantInvalidatePropagation()) {
|
||||||
|
if (!lay || lay->isActivated()) {
|
||||||
|
QApplication::sendEvent(this, &re);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
QApplication::sendEvent(this, &re);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
QSizeF oldSize = size();
|
|
||||||
QGraphicsLayoutItem::setGeometry(newGeom);
|
|
||||||
// Send resize event
|
|
||||||
bool resized = newGeom.size() != oldSize;
|
|
||||||
if (resized) {
|
|
||||||
QGraphicsSceneResizeEvent re;
|
|
||||||
re.setOldSize(oldSize);
|
|
||||||
re.setNewSize(newGeom.size());
|
|
||||||
if (oldSize.width() != newGeom.size().width())
|
|
||||||
emit widthChanged();
|
|
||||||
if (oldSize.height() != newGeom.size().height())
|
|
||||||
emit heightChanged();
|
|
||||||
QApplication::sendEvent(this, &re);
|
|
||||||
}
|
|
||||||
emit geometryChanged();
|
emit geometryChanged();
|
||||||
|
relayoutChildrenAndReturn:
|
||||||
|
if (QGraphicsLayout::instantInvalidatePropagation()) {
|
||||||
|
if (QGraphicsLayout *lay = wd->layout) {
|
||||||
|
if (!lay->isActivated()) {
|
||||||
|
QEvent layoutRequest(QEvent::LayoutRequest);
|
||||||
|
QApplication::sendEvent(this, &layoutRequest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -1052,16 +1074,31 @@ void QGraphicsWidget::updateGeometry()
|
|||||||
QGraphicsLayoutItem *parentItem = parentLayoutItem();
|
QGraphicsLayoutItem *parentItem = parentLayoutItem();
|
||||||
|
|
||||||
if (parentItem && parentItem->isLayout()) {
|
if (parentItem && parentItem->isLayout()) {
|
||||||
parentItem->updateGeometry();
|
if (QGraphicsLayout::instantInvalidatePropagation()) {
|
||||||
|
static_cast<QGraphicsLayout *>(parentItem)->invalidate();
|
||||||
|
} else {
|
||||||
|
parentItem->updateGeometry();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (parentItem) {
|
if (parentItem) {
|
||||||
|
// This is for custom layouting
|
||||||
QGraphicsWidget *parentWid = parentWidget(); //###
|
QGraphicsWidget *parentWid = parentWidget(); //###
|
||||||
if (parentWid->isVisible())
|
if (parentWid->isVisible())
|
||||||
QApplication::postEvent(parentWid, new QEvent(QEvent::LayoutRequest));
|
QApplication::postEvent(parentWid, new QEvent(QEvent::LayoutRequest));
|
||||||
|
} else {
|
||||||
|
/**
|
||||||
|
* If this is the topmost widget, post a LayoutRequest event to the widget.
|
||||||
|
* When the event is received, it will start flowing all the way down to the leaf
|
||||||
|
* widgets in one go. This will make a relayout flicker-free.
|
||||||
|
*/
|
||||||
|
if (QGraphicsLayout::instantInvalidatePropagation())
|
||||||
|
QApplication::postEvent(static_cast<QGraphicsWidget *>(this), new QEvent(QEvent::LayoutRequest));
|
||||||
|
}
|
||||||
|
if (!QGraphicsLayout::instantInvalidatePropagation()) {
|
||||||
|
bool wasResized = testAttribute(Qt::WA_Resized);
|
||||||
|
resize(size()); // this will restrict the size
|
||||||
|
setAttribute(Qt::WA_Resized, wasResized);
|
||||||
}
|
}
|
||||||
bool wasResized = testAttribute(Qt::WA_Resized);
|
|
||||||
resize(size()); // this will restrict the size
|
|
||||||
setAttribute(Qt::WA_Resized, wasResized);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1091,6 +1091,9 @@ void tst_QGraphicsAnchorLayout::setSpacing()
|
|||||||
#ifdef Q_WS_MAC
|
#ifdef Q_WS_MAC
|
||||||
QTest::qWait(200);
|
QTest::qWait(200);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// 21x21
|
||||||
|
QCOMPARE(p->size(), QSizeF(41, 41));
|
||||||
QCOMPARE(a->geometry(), QRectF(0, 0, 20, 20));
|
QCOMPARE(a->geometry(), QRectF(0, 0, 20, 20));
|
||||||
QCOMPARE(b->geometry(), QRectF(21, 0, 20, 20));
|
QCOMPARE(b->geometry(), QRectF(21, 0, 20, 20));
|
||||||
QCOMPARE(c->geometry(), QRectF(0, 21, 41, 20));
|
QCOMPARE(c->geometry(), QRectF(0, 21, 41, 20));
|
||||||
|
@ -62,6 +62,7 @@ private slots:
|
|||||||
void compressLayoutRequest();
|
void compressLayoutRequest();
|
||||||
void automaticReparenting();
|
void automaticReparenting();
|
||||||
void verifyActivate();
|
void verifyActivate();
|
||||||
|
void invalidate();
|
||||||
void constructors();
|
void constructors();
|
||||||
void alternativeLayoutItems();
|
void alternativeLayoutItems();
|
||||||
void ownership();
|
void ownership();
|
||||||
@ -218,6 +219,7 @@ class TestLayout : public QGraphicsLinearLayout
|
|||||||
: QGraphicsLinearLayout(parent)
|
: QGraphicsLinearLayout(parent)
|
||||||
{
|
{
|
||||||
m_count = 0;
|
m_count = 0;
|
||||||
|
m_invalidateCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setGeometry(const QRectF &rect) {
|
void setGeometry(const QRectF &rect) {
|
||||||
@ -226,7 +228,12 @@ class TestLayout : public QGraphicsLinearLayout
|
|||||||
QGraphicsLinearLayout::setGeometry(rect);
|
QGraphicsLinearLayout::setGeometry(rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void invalidate() {
|
||||||
|
++m_invalidateCount;
|
||||||
|
QGraphicsLinearLayout::invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
int m_invalidateCount;
|
||||||
int m_count;
|
int m_count;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -251,6 +258,87 @@ void tst_QGraphicsLayout::verifyActivate()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tst_QGraphicsLayout::invalidate()
|
||||||
|
{
|
||||||
|
QGraphicsLayout::setInstantInvalidatePropagation(true);
|
||||||
|
QGraphicsScene scene;
|
||||||
|
QGraphicsView view(&scene);
|
||||||
|
|
||||||
|
TestGraphicsWidget *a = new TestGraphicsWidget;
|
||||||
|
scene.addItem(a);
|
||||||
|
TestLayout *alay = new TestLayout(a);
|
||||||
|
TestGraphicsWidget *b = new TestGraphicsWidget;
|
||||||
|
alay->addItem(b);
|
||||||
|
TestLayout *blay = new TestLayout(b);
|
||||||
|
TestGraphicsWidget *e = new TestGraphicsWidget;
|
||||||
|
blay->addItem(e);
|
||||||
|
|
||||||
|
|
||||||
|
TestGraphicsWidget *c = new TestGraphicsWidget;
|
||||||
|
alay->addItem(c);
|
||||||
|
TestLayout *clay = new TestLayout(c);
|
||||||
|
TestGraphicsWidget *f = new TestGraphicsWidget;
|
||||||
|
clay->addItem(f);
|
||||||
|
|
||||||
|
TestGraphicsWidget *d = new TestGraphicsWidget;
|
||||||
|
alay->addItem(d);
|
||||||
|
TestLayout *dlay = new TestLayout(d);
|
||||||
|
TestGraphicsWidget *g = new TestGraphicsWidget;
|
||||||
|
dlay->addItem(g);
|
||||||
|
|
||||||
|
view.show();
|
||||||
|
|
||||||
|
alay->m_invalidateCount = 0;
|
||||||
|
blay->m_invalidateCount = 0;
|
||||||
|
clay->m_invalidateCount = 0;
|
||||||
|
dlay->m_invalidateCount = 0;
|
||||||
|
|
||||||
|
QCoreApplication::sendPostedEvents();
|
||||||
|
QCoreApplication::processEvents();
|
||||||
|
|
||||||
|
alay->activate();
|
||||||
|
QCOMPARE(alay->isActivated(), true);
|
||||||
|
QCOMPARE(blay->isActivated(), true);
|
||||||
|
QCOMPARE(clay->isActivated(), true);
|
||||||
|
qDebug() << "alay->m_invalidateCount:" << alay->m_invalidateCount;
|
||||||
|
qDebug() << "blay->m_invalidateCount:" << blay->m_invalidateCount;
|
||||||
|
qDebug() << "clay->m_invalidateCount:" << clay->m_invalidateCount;
|
||||||
|
qDebug() << "dlay->m_invalidateCount:" << dlay->m_invalidateCount;
|
||||||
|
|
||||||
|
a->clearEventCount();
|
||||||
|
b->clearEventCount();
|
||||||
|
c->clearEventCount();
|
||||||
|
|
||||||
|
blay->invalidate();
|
||||||
|
QCOMPARE(alay->isActivated(), false);
|
||||||
|
QCOMPARE(blay->isActivated(), false);
|
||||||
|
QCOMPARE(clay->isActivated(), true);
|
||||||
|
QCOMPARE(a->eventCount(QEvent::LayoutRequest), 0);
|
||||||
|
QCOMPARE(b->eventCount(QEvent::LayoutRequest), 0);
|
||||||
|
QCOMPARE(c->eventCount(QEvent::LayoutRequest), 0);
|
||||||
|
|
||||||
|
|
||||||
|
alay->m_invalidateCount = 0;
|
||||||
|
blay->m_invalidateCount = 0;
|
||||||
|
clay->m_invalidateCount = 0;
|
||||||
|
dlay->m_invalidateCount = 0;
|
||||||
|
clay->invalidate();
|
||||||
|
QCOMPARE(alay->isActivated(), false);
|
||||||
|
QCOMPARE(blay->isActivated(), false);
|
||||||
|
QCOMPARE(clay->isActivated(), false);
|
||||||
|
|
||||||
|
QCoreApplication::sendPostedEvents();
|
||||||
|
QCOMPARE(a->eventCount(QEvent::LayoutRequest), 1);
|
||||||
|
QCOMPARE(b->eventCount(QEvent::LayoutRequest), 0);
|
||||||
|
QCOMPARE(c->eventCount(QEvent::LayoutRequest), 0);
|
||||||
|
qDebug() << "alay->m_invalidateCount:" << alay->m_invalidateCount;
|
||||||
|
qDebug() << "blay->m_invalidateCount:" << blay->m_invalidateCount;
|
||||||
|
qDebug() << "clay->m_invalidateCount:" << clay->m_invalidateCount;
|
||||||
|
qDebug() << "dlay->m_invalidateCount:" << dlay->m_invalidateCount;
|
||||||
|
|
||||||
|
QGraphicsLayout::setInstantInvalidatePropagation(false);
|
||||||
|
}
|
||||||
|
|
||||||
class Layout : public QGraphicsLayout
|
class Layout : public QGraphicsLayout
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -94,6 +94,7 @@ private slots:
|
|||||||
void itemSpacing();
|
void itemSpacing();
|
||||||
void setStretchFactor_data();
|
void setStretchFactor_data();
|
||||||
void setStretchFactor();
|
void setStretchFactor();
|
||||||
|
void testStretch();
|
||||||
void defaultStretchFactors_data();
|
void defaultStretchFactors_data();
|
||||||
void defaultStretchFactors();
|
void defaultStretchFactors();
|
||||||
void sizeHint_data();
|
void sizeHint_data();
|
||||||
@ -667,6 +668,10 @@ void tst_QGraphicsLinearLayout::invalidate()
|
|||||||
layout.setContentsMargins(0, 0, 0, 0);
|
layout.setContentsMargins(0, 0, 0, 0);
|
||||||
view.show();
|
view.show();
|
||||||
widget->show();
|
widget->show();
|
||||||
|
//QTest::qWait(1000);
|
||||||
|
QTest::qWaitForWindowShown(&view);
|
||||||
|
qApp->processEvents();
|
||||||
|
layout.layoutRequest = 0;
|
||||||
|
|
||||||
layout.setContentsMargins(1, 2, 3, 4);
|
layout.setContentsMargins(1, 2, 3, 4);
|
||||||
QApplication::sendPostedEvents(0, 0);
|
QApplication::sendPostedEvents(0, 0);
|
||||||
@ -1130,6 +1135,41 @@ void tst_QGraphicsLinearLayout::setStretchFactor()
|
|||||||
delete widget;
|
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()
|
void tst_QGraphicsLinearLayout::defaultStretchFactors_data()
|
||||||
{
|
{
|
||||||
QTest::addColumn<Qt::Orientation>("orientation");
|
QTest::addColumn<Qt::Orientation>("orientation");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user