QtBase  v6.3.1
tst_qgraphicslayout.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the test suite of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21 ** included in the packaging of this file. Please review the following
22 ** information to ensure the GNU General Public License requirements will
23 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24 **
25 ** $QT_END_LICENSE$
26 **
27 ****************************************************************************/
28 
29 
30 #include <QTest>
31 #include <QtGui>
32 #include <QtWidgets>
33 #include <math.h>
34 
36 {
38 
39 public:
41  virtual ~tst_QGraphicsLayout();
42 
43 private slots:
44  void sizeHints();
45  void compressLayoutRequest();
46  void automaticReparenting();
47  void verifyActivate();
48  void sizeHintOfHiddenLayout();
49  void invalidate();
50  void constructors();
51  void alternativeLayoutItems();
52  void ownership();
53 };
54 
56 {
57 }
58 
60 {
61 }
62 
63 void tst_QGraphicsLayout::sizeHints()
64 {
65 
71  lout->setContentsMargins(0,0,0,0);
73  gw->setMinimumSize(QSizeF(10,10));
74  gw->setPreferredSize(QSizeF(100,100));
75  gw->setMaximumSize(QSizeF(500,500));
76  lout->addItem(gw);
80 
81 }
82 
87 };
88 
89 
90 
92 public:
94  { }
95 
96  bool event(QEvent *e) override
97  {
98  ++(m_eventCount[int(e->type())]);
99  return QGraphicsWidget::event(e);
100  }
101 
103  return m_eventCount.value(int(type));
104  }
105 
107  m_eventCount.clear();
108  }
109 
110  void clearCounters() {
111  m_eventCount.clear();
113  }
114 
115  void setGeometry(const QRectF &rect) override
116  {
119  }
120 
122  {
123  // updateGeometry() is protected
125  }
127 private:
128  QMap<int, int> m_eventCount;
129 };
130 
131 void tst_QGraphicsLayout::compressLayoutRequest()
132 {
136  scene.addItem(tw);
137  view.show();
138 
141  for (int i = 0; i < 4; ++i) {
142  QGraphicsWidget *gw = new QGraphicsWidget(tw);
143  gw->setPreferredSize(QSizeF(50, 50));
144  lout->addItem(gw);
145  }
148 }
149 
150 void tst_QGraphicsLayout::automaticReparenting()
151 {
154  {
158  l->addItem(w1);
159  scene.addItem(w);
160  QCOMPARE(w1->parentWidget(), w);
161  delete w;
162  }
163  {
167  l->addItem(w1);
168  scene.addItem(w);
169  QCOMPARE(w1->parentWidget(), w);
170 
171  QGraphicsWidget *ww = new QGraphicsWidget();
173 #if !defined(Q_OS_MAC) && defined(QT_DEBUG)
174  QTest::ignoreMessage(QtWarningMsg, "QGraphicsLayout::addChildLayoutItem: QGraphicsWidget \"\""
175  " in wrong parent; moved to correct parent");
176 #endif
177  l1->addItem(w1);
178  QCOMPARE(w1->parentWidget(), ww);
179  delete w;
180  }
181 
184  view.show();
187  l1->addItem(w1);
189  l1->addItem(w2);
190  QCOMPARE(w1->parentItem(), nullptr);
191  QCOMPARE(w2->parentItem(), nullptr);
192  scene.addItem(w1);
193  QCOMPARE(w1->parentItem(), nullptr);
194  window->setLayout(l1);
195  QCOMPARE(w1->parentItem(), static_cast<QGraphicsItem*>(window));
196  QCOMPARE(w2->parentItem(), static_cast<QGraphicsItem*>(window));
197 
198  // Sublayouts
200  QGraphicsWidget *w3 = new QGraphicsWidget();
201  l2->addItem(w3);
202  QGraphicsWidget *w4 = new QGraphicsWidget();
203  l2->addItem(w4);
205  l2->addItem(l3);
206  QGraphicsWidget *window2 = new QGraphicsWidget();
207  scene.addItem(window2);
208  window2->setLayout(l2);
209 
210  QCOMPARE(w3->parentItem(), static_cast<QGraphicsItem*>(window2));
211  QCOMPARE(w4->parentItem(), static_cast<QGraphicsItem*>(window2));
212 
213  // graphics item with another parent
215  l5->addItem(w1);
216  l5->addItem(w2);
217  QCOMPARE(w1->parentItem(), static_cast<QGraphicsItem*>(window));
218  QCOMPARE(w2->parentItem(), static_cast<QGraphicsItem*>(window));
220  l4->addItem(l5);
221  QGraphicsWidget *window3 = new QGraphicsWidget();
222  scene.addItem(window3);
223  window3->setLayout(l4);
224 
225  QCOMPARE(w1->parentItem(), static_cast<QGraphicsItem*>(window3));
226  QCOMPARE(w2->parentItem(), static_cast<QGraphicsItem*>(window3));
227 }
228 
230 {
231  public:
234  {
235  setContentsMargins(0,0,0,0);
236  setSpacing(0);
237  }
238 
239  void setGeometry(const QRectF &rect) override
240  {
243  }
244 
245  void invalidate() override
246  {
249  }
250 
251  void clearCounters() {
253  }
254 
256 };
257 
258 void tst_QGraphicsLayout::verifyActivate()
259 {
262 
265  TestLayout *lout = new TestLayout(window);
267  lout->addItem(w);
268  window->setLayout(lout);
269 
271  window->setVisible(false);
273  window->setVisible(true);
274  // on polish or the first time a widget is shown, the widget is resized.
276 
277 }
278 
279 
280 void tst_QGraphicsLayout::sizeHintOfHiddenLayout()
281 {
284 
287  TestLayout *lout = new TestLayout(window);
288  lout->setContentsMargins(1,2,2,1);
290  w->setPreferredSize(20, 20);
291  w->setMaximumSize(50, 50);
292  lout->addItem(w);
293  window->setLayout(lout);
294 
295  for (int pass = 0; pass < 3; ++pass) {
296  QCOMPARE(lout->sizeHint(Qt::MinimumSize), QSizeF(3,3));
297  QCOMPARE(lout->sizeHint(Qt::PreferredSize), QSizeF(23,23));
298  QCOMPARE(lout->sizeHint(Qt::MaximumSize), QSizeF(53,53));
299  window->setVisible(pass % 2);
300  }
301 }
302 
303 static void clearAllCounters(TestGraphicsWidget *widget)
304 {
305  if (!widget)
306  return;
307  widget->clearCounters();
308  TestLayout *layout = static_cast<TestLayout *>(widget->layout());
309  if (layout) {
310  layout->clearCounters();
311  for (int i = layout->count() - 1; i >=0; --i) {
313  if (item->isLayout()) {
314  // ### Not used ATM
315  //TestLayout *lay = static_cast<TestLayout*>(static_cast<QGraphicsLayout*>(item));
316  //clearAllCounters(lay);
317  } else {
318  TestGraphicsWidget *wid = static_cast<TestGraphicsWidget *>(item);
319  clearAllCounters(wid);
320  }
321  }
322  }
323 }
324 
325 static void activateAndReset(TestGraphicsWidget *widget)
326 {
329  if (widget->layout())
330  widget->layout()->activate();
331  clearAllCounters(widget);
332 }
333 
334 
335 void tst_QGraphicsLayout::invalidate()
336 {
340 
342  a->setData(0, QString("a"));
343  scene.addItem(a);
344  TestLayout *alay = new TestLayout(a);
346  b->setData(0, QString("b"));
347  alay->addItem(b);
348  TestLayout *blay = new TestLayout(b);
350  e->setData(0, QString("e"));
351  blay->addItem(e);
352 
353 
355  c->setData(0, QString("c"));
356  alay->addItem(c);
357  TestLayout *clay = new TestLayout(c);
359  f->setData(0, QString("f"));
360  clay->addItem(f);
361 
363  d->setData(0, QString("d"));
364  alay->addItem(d);
365  TestLayout *dlay = new TestLayout(d);
367  g->setData(0, QString("g"));
368  dlay->addItem(g);
369 
370  view.show();
371 
372  {
373  clearAllCounters(a);
374 
377 
378  alay->activate();
379  QCOMPARE(alay->isActivated(), true);
380  QCOMPARE(blay->isActivated(), true);
381  QCOMPARE(clay->isActivated(), true);
382  QCOMPARE(dlay->isActivated(), true);
383  }
384 
385  {
386  clearAllCounters(a);
387  e->callUpdateGeometry();
388  QCOMPARE(alay->isActivated(), false);
389  QCOMPARE(blay->isActivated(), false);
390  QCOMPARE(clay->isActivated(), true);
391  QCOMPARE(dlay->isActivated(), true);
392  QCOMPARE(a->eventCount(QEvent::LayoutRequest), 0);
393  QCOMPARE(b->eventCount(QEvent::LayoutRequest), 0);
394  QCOMPARE(c->eventCount(QEvent::LayoutRequest), 0);
395  QCOMPARE(d->eventCount(QEvent::LayoutRequest), 0);
396 
397  // should only invalidate ascendants of e
398  QCOMPARE(blay->functionCount[Invalidate], 1);
399  QCOMPARE(alay->functionCount[Invalidate], 1);
400  // not siblings
401  QCOMPARE(clay->functionCount[Invalidate], 0);
402  QCOMPARE(dlay->functionCount[Invalidate], 0);
403 
405  QCOMPARE(a->eventCount(QEvent::LayoutRequest), 1);
406  QCOMPARE(b->eventCount(QEvent::LayoutRequest), 1);
407  QCOMPARE(c->eventCount(QEvent::LayoutRequest), 0);
408  QCOMPARE(d->eventCount(QEvent::LayoutRequest), 0);
409  }
410 
411 
412  {
413  activateAndReset(a);
414  f->callUpdateGeometry();
415  QCOMPARE(alay->isActivated(), false);
416  QCOMPARE(blay->isActivated(), true);
417  QCOMPARE(clay->isActivated(), false);
418  QCOMPARE(dlay->isActivated(), true);
419 
421  QCOMPARE(a->eventCount(QEvent::LayoutRequest), 1);
422  QCOMPARE(b->eventCount(QEvent::LayoutRequest), 0);
423  QCOMPARE(c->eventCount(QEvent::LayoutRequest), 1);
424  QCOMPARE(d->eventCount(QEvent::LayoutRequest), 0);
425 
426  QCOMPARE(a->functionCount[SetGeometry], 1);
428 
429  QCOMPARE(b->functionCount[SetGeometry], 1);
430  QCOMPARE(c->functionCount[SetGeometry], 1);
431  QCOMPARE(d->functionCount[SetGeometry], 1);
432  // Since nothing really changed, blay and dlay don't need
433  // to be resized.
437 
438  QCOMPARE(f->functionCount[SetGeometry], 1);
439 
440  QCOMPARE(a->size(), QSizeF(150, 50));
441  }
442 
443  {
444  activateAndReset(a);
445  f->setPreferredSize(QSizeF(60,50));
446  QCOMPARE(alay->isActivated(), false);
447  QCOMPARE(blay->isActivated(), true);
448  QCOMPARE(clay->isActivated(), false);
449  QCOMPARE(dlay->isActivated(), true);
450 
451  QCOMPARE(c->eventCount(QEvent::LayoutRequest), 0);
453  QCOMPARE(a->eventCount(QEvent::LayoutRequest), 1);
454  QCOMPARE(b->eventCount(QEvent::LayoutRequest), 0);
455  QCOMPARE(c->eventCount(QEvent::LayoutRequest), 1);
456  QCOMPARE(d->eventCount(QEvent::LayoutRequest), 0);
457 
458  QCOMPARE(a->functionCount[SetGeometry], 1);
460 
461  QCOMPARE(b->functionCount[SetGeometry], 1);
462  QCOMPARE(c->functionCount[SetGeometry], 1);
463  QCOMPARE(d->functionCount[SetGeometry], 1);
464  // f actually got wider, need to rearrange its siblings
468 
469  QCOMPARE(e->functionCount[SetGeometry], 1);
470  QCOMPARE(f->functionCount[SetGeometry], 1);
471  QCOMPARE(g->functionCount[SetGeometry], 1);
472 
473  QVERIFY(e->size().width() < f->size().width());
474  QVERIFY(g->size().width() < f->size().width());
475  }
476 
477  {
478  // resize f so much that it'll force a resize of the top widget
479  // this will currently generate two setGeometry() calls on the child layout
480  // of the top widget.
481  activateAndReset(a);
482  f->setPreferredSize(QSizeF());
483  f->setMinimumSize(QSizeF(200,50));
484  QCOMPARE(alay->isActivated(), false);
485  QCOMPARE(blay->isActivated(), true);
486  QCOMPARE(clay->isActivated(), false);
487  QCOMPARE(dlay->isActivated(), true);
488 
489  QCOMPARE(c->eventCount(QEvent::LayoutRequest), 0);
491  QCOMPARE(a->eventCount(QEvent::LayoutRequest), 1);
492  QCOMPARE(b->eventCount(QEvent::LayoutRequest), 0);
493  QCOMPARE(c->eventCount(QEvent::LayoutRequest), 1);
494  QCOMPARE(d->eventCount(QEvent::LayoutRequest), 0);
495 
496  QCOMPARE(a->functionCount[SetGeometry], 1);
497 
498  /* well, ideally one call to setGeometry(), but it will currently
499  * get two calls to setGeometry():
500  * 1. The first LayoutRequest will call activate() - that will call
501  * setGeometry() on the layout. This geometry will be based on
502  * the widget geometry which is not correct at this moment.
503  * (it is still 150 wide)
504  * 2. Next, we check if the widget is top level, and then we call
505  * parentWidget->resize(parentWidget->size());
506  * This will be adjusted to be minimum 200 pixels wide.
507  * The new size will then be propagated down to the layout
508  *
509  */
511 
512  QCOMPARE(b->functionCount[SetGeometry], 2);
513  QCOMPARE(c->functionCount[SetGeometry], 2);
514  QCOMPARE(d->functionCount[SetGeometry], 2);
515  // f actually got wider, need to rearrange its siblings
519 
520  QCOMPARE(e->functionCount[SetGeometry], 1);
521  QCOMPARE(f->functionCount[SetGeometry], 1);
522  QCOMPARE(g->functionCount[SetGeometry], 1);
523 
524  QVERIFY(e->size().width() < f->size().width());
525  QVERIFY(g->size().width() < f->size().width());
526  }
527 
528  {
529  f->setPreferredSize(QSizeF());
530  f->setMinimumSize(QSizeF());
531  a->adjustSize();
532  activateAndReset(a);
533  // update two different leaf widgets,
534  // eventCount and functionCount should never be >= 2
535  e->callUpdateGeometry();
536  g->callUpdateGeometry();
537  QCOMPARE(alay->isActivated(), false);
538  QCOMPARE(blay->isActivated(), false);
539  QCOMPARE(clay->isActivated(), true);
540  QCOMPARE(dlay->isActivated(), false);
541 
543  QCOMPARE(a->eventCount(QEvent::LayoutRequest), 1);
544  QCOMPARE(b->eventCount(QEvent::LayoutRequest), 1);
545  QCOMPARE(c->eventCount(QEvent::LayoutRequest), 0);
546  QCOMPARE(d->eventCount(QEvent::LayoutRequest), 1);
547 
548  QCOMPARE(a->functionCount[SetGeometry], 1);
550 
551  QCOMPARE(b->functionCount[SetGeometry], 1);
552  QCOMPARE(c->functionCount[SetGeometry], 1);
553  QCOMPARE(d->functionCount[SetGeometry], 1);
554  // f actually got wider, need to rearrange its siblings
558 
559  QCOMPARE(e->functionCount[SetGeometry], 1);
560  QCOMPARE(f->functionCount[SetGeometry], 0);
561  QCOMPARE(g->functionCount[SetGeometry], 1);
562 
563  }
564 
566 }
567 
568 class Layout : public QGraphicsLayout
569 {
570 public:
571  Layout(QGraphicsLayoutItem *parentItem = 0) : QGraphicsLayout(parentItem) {}
572 
573  void setGeometry(const QRectF &rect) override
574  {
576  }
577 
578  int count() const override
579  {
580  return 0;
581  }
582 
583  QGraphicsLayoutItem *itemAt(int index) const override
584  {
585  Q_UNUSED(index);
586  return 0;
587  }
588 
589  void removeAt(int index) override
590  {
591  Q_UNUSED(index);
592  }
593 
594 protected:
595  QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const override
596  {
597  Q_UNUSED(constraint);
598  Q_UNUSED(which);
599  return QSizeF(100,100);
600  }
601 
602 };
603 
604 void tst_QGraphicsLayout::constructors()
605 {
606  // Strange test, but see the fix that was with this submit
607  QList<Layout *> layouts;
608  for (int pass = 0; pass < 5; ++pass) {
609  Layout *lay = new Layout();
610  layouts << lay;
612  lay->getContentsMargins(&left, &top, &right, &bottom);
613  // Test if the style defaults are sane (should always be ints)
614  double intpart;
615  QVERIFY(modf(left, &intpart) == 0.0);
616  QVERIFY(modf(top, &intpart) == 0.0);
617  QVERIFY(modf(right, &intpart) == 0.0);
618  QVERIFY(modf(bottom, &intpart) == 0.0);
619 
620  lay->setContentsMargins(1, 2, 4, 8);
621  lay->getContentsMargins(&left, &top, &right, &bottom);
622 
623  QCOMPARE(int(left), 1);
624  QCOMPARE(int(top), 2);
625  QCOMPARE(int(right), 4);
626  QCOMPARE(int(bottom), 8);
627  }
628 
629  qDeleteAll(layouts);
630 }
631 
633 public:
636  {
638  }
639 
640  void setGeometry(const QRectF &geom) override;
641 
642  QSizeF sizeHint(Qt::SizeHint which, const QSizeF & constraint = QSizeF() ) const override;
643 
645  return static_cast<QGraphicsRectItem *>(graphicsItem());
646  }
647 
649 private:
650  AnimatedLayoutItem() {}
651 };
652 
654 {
656 }
657 
658 QSizeF AnimatedLayoutItem::sizeHint(Qt::SizeHint which, const QSizeF & /* constraint */) const
659 {
660  switch (which) {
661  case Qt::MinimumSize:
662  return QSizeF(32,32);
663  case Qt::PreferredSize:
664  return QSizeF(160,90);
665  case Qt::MaximumSize:
666  return QSizeF(1000,1000);
667  default:
668  return QSizeF(300, 300);
669  }
670 }
671 
673  Q_OBJECT
674 public:
676  {
677  connect(&m_timeline, SIGNAL(valueChanged(qreal)), this, SLOT(valueChanged(qreal)));
678  }
679 
680  void setGeometry(const QRectF &geom) override
681  {
682  fromGeoms.clear();
683  toGeoms.clear();
684  for (int i = 0; i < count(); ++i) {
685  fromGeoms << itemAt(i)->geometry();
686  }
687 
689 
690  for (int i = 0; i < count(); ++i) {
691  toGeoms << itemAt(i)->geometry();
692  }
693  m_timeline.start();
694  }
695 
696 private slots:
697  void valueChanged(qreal value) {
698  for (int i = 0; i < fromGeoms.count(); ++i) {
700  QRectF from = fromGeoms.at(i);
701  QRectF to = toGeoms.at(i);
702 
703  QRectF geom(from.topLeft() + (to.topLeft() - from.topLeft()) * value,
704  from.size() + (to.size() - from.size()) * value);
705  static_cast<QGraphicsRectItem*>(li->graphicsItem())->setRect(geom);
706  }
707  }
708 private:
709  QTimeLine m_timeline;
710  QList<QRectF> fromGeoms;
711  QList<QRectF> toGeoms;
712 };
713 
714 
715 void tst_QGraphicsLayout::alternativeLayoutItems()
716 {
719 
722  AnimatedLayout *lout = new AnimatedLayout(window);
723  lout->setContentsMargins(0, 0, 0, 0);
724  lout->setSpacing(0);
725 
727  AnimatedLayoutItem *li1 = new AnimatedLayoutItem(item1);
728  lout->addItem(li1);
729 
731  AnimatedLayoutItem *li2 = new AnimatedLayoutItem(item2);
732  lout->addItem(li2);
733 
735  AnimatedLayoutItem *li3 = new AnimatedLayoutItem(item3);
736  lout->addItem(li3);
737 
738  window->setLayout(lout);
739 
740  window->setGeometry(0, 0, 99, 99);
741  view.setSceneRect(QRectF(-10, -10, 110, 110));
742  view.resize(150, 150);
743  view.show();
744 
745  QTRY_COMPARE(static_cast<QGraphicsRectItem*>(li1->graphicsItem())->rect(), QRectF( 0, 0, 33, 99));
746  QTRY_COMPARE(static_cast<QGraphicsRectItem*>(li2->graphicsItem())->rect(), QRectF(33, 0, 33, 99));
747  QTRY_COMPARE(static_cast<QGraphicsRectItem*>(li3->graphicsItem())->rect(), QRectF(66, 0, 33, 99));
748 
750 
751  QTRY_COMPARE(static_cast<QGraphicsRectItem*>(li1->graphicsItem())->rect(), QRectF(0, 0, 99, 33));
752  QTRY_COMPARE(static_cast<QGraphicsRectItem*>(li2->graphicsItem())->rect(), QRectF(0, 33, 99, 33));
753  QTRY_COMPARE(static_cast<QGraphicsRectItem*>(li3->graphicsItem())->rect(), QRectF(0, 66, 99, 33));
754 
755 }
756 
758 public:
761  {
762  m_destructedSet = destructedSet;
763  setOwnedByLayout(true);
764  }
765 
766  QSizeF sizeHint(Qt::SizeHint which, const QSizeF & constraint = QSizeF() ) const override;
767 
769  m_destructedSet->insert(this);
770  }
771 private:
772  QSet<QGraphicsLayoutItem*> *m_destructedSet;
773 };
774 
775 QSizeF CustomLayoutItem::sizeHint(Qt::SizeHint which, const QSizeF & /* constraint */) const
776 {
777  switch (which) {
778  case Qt::MinimumSize:
779  return QSizeF(32,32);
780  case Qt::PreferredSize:
781  return QSizeF(160,90);
782  case Qt::MaximumSize:
783  return QSizeF(1000,1000);
784  default:
785  return QSizeF(300, 300);
786  }
787 }
788 
790 public:
792  : QGraphicsWidget()
793  {
794  m_destructedSet = destructedSet;
795  }
796 
797  QSizeF sizeHint(Qt::SizeHint which, const QSizeF & constraint = QSizeF() ) const override;
798 
800  {
801  const QRect r = option->rect.adjusted(0, 0, -1, -1);
802  painter->drawLine(r.topLeft(), r.bottomRight());
803  painter->drawLine(r.bottomLeft(), r.topRight());
804  painter->drawRect(r);
805  }
806 
808  if (m_destructedSet)
809  m_destructedSet->insert(this);
810  }
811 private:
812  QSet<QGraphicsLayoutItem*> *m_destructedSet;
813 };
814 
815 QSizeF CustomGraphicsWidget::sizeHint(Qt::SizeHint which, const QSizeF & /* constraint */) const
816 {
817  switch (which) {
818  case Qt::MinimumSize:
819  return QSizeF(32,32);
820  case Qt::PreferredSize:
821  return QSizeF(160,90);
822  case Qt::MaximumSize:
823  return QSizeF(1000,1000);
824  default:
825  return QSizeF(300, 300);
826  }
827 }
828 
829 static bool compareSets(const QSet<QGraphicsLayoutItem*> &actual, const QSet<QGraphicsLayoutItem*> &expected)
830 {
831  if (actual != expected) {
832  qDebug() << "actual:" << actual << "expected:" << expected;
833  return false;
834  }
835  return true;
836 }
837 
839 {
840 public :
843 {
844 }
845 
846 
848 {
849 }
850 
851 int count() const override
852 {
853  return items.count();
854 }
855 
856 QGraphicsLayoutItem* itemAt(int index) const override
857 {
858  return items.at(index);
859 }
860 
861 
862 void removeAt(int index) override
863 {
865 }
866 
868 {
870 }
871 
873 {
874  index = qBound(0, index, items.count());
875 
876  item->setParentLayoutItem(this);
877 
878  QGraphicsWidget *widget = static_cast<QGraphicsWidget *>(item);
880 
881 
882  if (index == items.count()) {
883  items.append(item);
884  } else {
886  }
887 
888  updateGeometry();
889  activate();
890 }
891 
893 {
894  QGraphicsLayoutItem *parentItem = parentLayoutItem();
895  while (parentItem && parentItem->isLayout()) {
896  parentItem = parentItem->parentLayoutItem();
897  }
898 
899  if (parentItem) {
900  item->setParentItem(static_cast<QGraphicsWidget*>(parentItem));
901  }
902 }
903 
904 QSizeF sizeHint(Qt::SizeHint /* which */, const QSizeF & /* constraint */) const override
905 {
906  return QSizeF(50,50);
907 }
908 
910 
911 };
912 
913 void tst_QGraphicsLayout::ownership()
914 {
917 
918  {
920  QSet<QGraphicsLayoutItem*> destructedSet;
921  CustomLayoutItem *li1 = new CustomLayoutItem(&destructedSet);
922  lay->addItem(li1);
923  CustomLayoutItem *li2 = new CustomLayoutItem(&destructedSet);
924  lay->addItem(li2);
925  CustomLayoutItem *li3 = new CustomLayoutItem(&destructedSet);
926  lay->addItem(li3);
927  destructedSet.clear();
928 
929  delete lay;
931  expected << li1 << li2 << li3;
932  QVERIFY(compareSets(destructedSet, expected));
933  }
934 
935  {
938  QSet<QGraphicsLayoutItem*> destructedSet;
939  CustomGraphicsWidget *li1 = new CustomGraphicsWidget(&destructedSet);
940  lay->addItem(li1);
941  CustomGraphicsWidget *li2 = new CustomGraphicsWidget(&destructedSet);
942  lay->addItem(li2);
943  CustomGraphicsWidget *li3 = new CustomGraphicsWidget(&destructedSet);
944  lay->addItem(li3);
945  window->setLayout(lay);
947 
948  destructedSet.clear();
949  window->setLayout(0);
950  QCOMPARE(destructedSet.count(), 0);
951  delete window;
952  }
953 
954  {
957 
959  lay->addItem(li1);
960 
963  li2->addItem(li2_1);
965  li2->addItem(li2_2);
967  li2->addItem(li2_3);
968  lay->addItem(li2);
969 
971  lay->addItem(li3);
972 
973  window->setLayout(lay);
975  view.resize(500, 200);
976  view.show();
977 
978  for (int i = li2->count(); i > 0; --i) {
979  QCOMPARE(li2->count(), i);
980  delete li2->itemAt(0);
981  }
982 
983  for (int i = lay->count(); i > 0; --i) {
984  QCOMPARE(lay->count(), i);
985  delete lay->itemAt(0);
986  }
987 
988  delete window;
989  }
990 
991  {
996  layout->addItem(w);
997  layout->addItem(w2);
998  top->setLayout(layout);
999  delete top;
1000  //don't crash after that.
1001  }
1002 }
1003 
1005 #include "tst_qgraphicslayout.moc"
small capitals from c petite p scientific i
[1]
Definition: afcover.h:80
@ SetGeometry
@ NumFunctionTypes
@ Invalidate
void setGeometry(const QRectF &geom) override
AnimatedLayout(QGraphicsWidget *widget)
void setGeometry(const QRectF &geom) override
AnimatedLayoutItem(QGraphicsRectItem *item)
QGraphicsRectItem * rectItem()
QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint=QSizeF()) const override
CustomGraphicsWidget(QSet< QGraphicsLayoutItem * > *destructedSet=0)
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *=0) override
QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint=QSizeF()) const override
QGraphicsLayoutItem * itemAt(int index) const override
CustomLayout(QGraphicsLayoutItem *parent)
QSizeF sizeHint(Qt::SizeHint, const QSizeF &) const override
QList< QGraphicsLayoutItem * > items
int count() const override
void insertItem(int index, QGraphicsLayoutItem *item)
void removeAt(int index) override
void updateParentWidget(QGraphicsWidget *item)
void addItem(QGraphicsLayoutItem *item)
QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint=QSizeF()) const override
CustomLayoutItem(QSet< QGraphicsLayoutItem * > *destructedSet)
void removeAt(int index) override
void setGeometry(const QRectF &rect) override
Layout(QGraphicsLayoutItem *parentItem=0)
QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint=QSizeF()) const override
QGraphicsLayoutItem * itemAt(int index) const override
int count() const override
int count() const override
Definition: qboxlayout.cpp:707
void addItem(QLayoutItem *) override
Definition: qboxlayout.cpp:832
QLayoutItem * itemAt(int) const override
Definition: qboxlayout.cpp:716
static void processEvents(QEventLoop::ProcessEventsFlags flags=QEventLoop::AllEvents)
static void sendPostedEvents(QObject *receiver=nullptr, int event_type=0)
The QEvent class is the base class of all event classes. Event objects contain event parameters.
Definition: qcoreevent.h:58
@ LayoutRequest
Definition: qcoreevent.h:125
The QGraphicsItem class is the base class for all graphical items in a QGraphicsScene.
Definition: qgraphicsitem.h:83
void setData(int key, const QVariant &value)
void setParentItem(QGraphicsItem *parent)
QGraphicsItem * parentItem() const
The QGraphicsLayout class provides the base class for all layouts in Graphics View.
virtual void updateGeometry() override
static void setInstantInvalidatePropagation(bool enable)
bool isActivated() const
void getContentsMargins(qreal *left, qreal *top, qreal *right, qreal *bottom) const override
void setContentsMargins(qreal left, qreal top, qreal right, qreal bottom)
The QGraphicsLayoutItem class can be inherited to allow your custom items to be managed by layouts.
void setGraphicsItem(QGraphicsItem *item)
QGraphicsItem * graphicsItem() const
QSizeF effectiveSizeHint(Qt::SizeHint which, const QSizeF &constraint=QSizeF()) const
void setMaximumSize(const QSizeF &size)
void setOwnedByLayout(bool ownedByLayout)
void setPreferredSize(const QSizeF &size)
QGraphicsLayoutItem * parentLayoutItem() const
void setMinimumSize(const QSizeF &size)
virtual void setGeometry(const QRectF &rect)
The QGraphicsLinearLayout class provides a horizontal or vertical layout for managing widgets in Grap...
QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint=QSizeF()) const override
void setOrientation(Qt::Orientation orientation)
void setSpacing(qreal spacing)
void setGeometry(const QRectF &rect) override
void addItem(QGraphicsLayoutItem *item)
QGraphicsLayoutItem * itemAt(int index) const override
int count() const override
QGraphicsObject * parent
the parent of the item
The QGraphicsRectItem class provides a rectangle item that you can add to a QGraphicsScene.
QRectF rect() const
The QGraphicsScene class provides a surface for managing a large number of 2D graphical items.
void addItem(QGraphicsItem *item)
The QGraphicsView class provides a widget for displaying the contents of a QGraphicsScene.
Definition: qgraphicsview.h:60
The QGraphicsWidget class is the base class for all widget items in a QGraphicsScene.
void setLayout(QGraphicsLayout *layout)
QRectF rect() const
void setGeometry(const QRectF &rect) override
bool event(QEvent *event) override
void updateGeometry() override
bool activate()
Definition: qlayout.cpp:1028
Definition: qlist.h:108
void removeAt(qsizetype i)
Definition: qlist.h:588
iterator insert(qsizetype i, parameter_type t)
Definition: qlist.h:499
const_reference at(qsizetype i) const noexcept
Definition: qlist.h:457
qsizetype count() const noexcept
Definition: qlist.h:415
void append(parameter_type t)
Definition: qlist.h:469
void clear()
Definition: qlist.h:445
T value(const Key &key, const T &defaultValue=T()) const
Definition: qmap.h:392
void clear()
Definition: qmap.h:324
The QObject class is the base class of all Qt objects.
Definition: qobject.h:125
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
Definition: qobject.cpp:2772
The QPainter class performs low-level painting on widgets and other paint devices.
Definition: qpainter.h:82
void drawRect(const QRectF &rect)
Definition: qpainter.h:554
void drawLine(const QLineF &line)
Definition: qpainter.h:477
The QRectF class defines a finite rectangle in the plane using floating point precision.
Definition: qrect.h:511
constexpr QPointF topLeft() const noexcept
Definition: qrect.h:538
constexpr QSizeF size() const noexcept
Definition: qrect.h:744
The QRect class defines a rectangle in the plane using integer precision.
Definition: qrect.h:59
constexpr QRect adjusted(int x1, int y1, int x2, int y2) const noexcept
Definition: qrect.h:397
qsizetype count() const
Definition: qset.h:190
void clear()
Definition: qset.h:97
iterator insert(const T &value)
Definition: qset.h:191
The QSizeF class defines the size of a two-dimensional object using floating point precision.
Definition: qsize.h:235
The QStyleOptionGraphicsItem class is used to describe the parameters needed to draw a QGraphicsItem.
Definition: qstyleoption.h:684
The QTimeLine class provides a timeline for controlling animations.
Definition: qtimeline.h:55
void start()
Definition: qtimeline.cpp:645
The QWidget class is the base class of all user interface objects.
Definition: qwidget.h:133
QLayout * layout() const
Definition: qwidget.cpp:10115
void setGeometry(const QRectF &rect) override
QMap< FunctionType, int > functionCount
int eventCount(QEvent::Type type)
bool event(QEvent *e) override
TestGraphicsWidget(QGraphicsWidget *parent=nullptr)
TestLayout(QGraphicsLayoutItem *parent=nullptr)
void setGeometry(const QRectF &rect) override
QMap< FunctionType, int > functionCount
void invalidate() override
#define this
Definition: dialogs.cpp:56
QOpenGLWidget * widget
[1]
qDeleteAll(list.begin(), list.end())
double e
QCOMPARE(spy.count(), 1)
rect
[4]
Q_GUI_EXPORT bool qWaitForWindowExposed(QWindow *window, int timeout=5000)
Q_TESTLIB_EXPORT void ignoreMessage(QtMsgType type, const char *message)
Definition: qtestcase.cpp:2292
@ Vertical
Definition: qnamespace.h:125
@ Window
Definition: qnamespace.h:232
SizeHint
Definition: qnamespace.h:1589
@ MaximumSize
Definition: qnamespace.h:1592
@ PreferredSize
Definition: qnamespace.h:1591
@ MinimumSize
Definition: qnamespace.h:1590
#define QString()
Definition: parse-defines.h:51
EGLOutputLayerEXT EGLint EGLAttrib value
QT_END_INCLUDE_NAMESPACE typedef double qreal
Definition: qglobal.h:341
#define qDebug
[1]
Definition: qlogging.h:177
@ QtWarningMsg
Definition: qlogging.h:62
#define SLOT(a)
Definition: qobjectdefs.h:87
#define SIGNAL(a)
Definition: qobjectdefs.h:88
GLenum type
Definition: qopengl.h:270
GLboolean GLboolean GLboolean b
GLboolean r
[2]
GLfloat GLfloat GLfloat w
[0]
GLboolean GLboolean GLboolean GLboolean a
[7]
GLuint index
[2]
GLdouble GLdouble GLdouble GLdouble top
GLdouble GLdouble right
GLfloat GLfloat f
GLint left
GLint GLint bottom
GLboolean GLboolean g
GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint GLdouble GLdouble w2
Definition: qopenglext.h:12395
const GLubyte * c
Definition: qopenglext.h:12701
GLuint GLenum option
Definition: qopenglext.h:5929
GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint GLdouble w1
Definition: qopenglext.h:12395
#define QTEST_MAIN(TestObject)
Definition: qtest.h:664
#define QTRY_COMPARE(expr, expected)
Definition: qtestcase.h:214
#define QVERIFY(statement)
Definition: qtestcase.h:64
#define Q_OBJECT
Definition: qtmetamacros.h:158
#define slots
Definition: qtmetamacros.h:76
Q_UNUSED(salary)
[21]
QVBoxLayout * layout
QGraphicsScene scene
[0]
QGraphicsItem * item
QPainter painter(this)
[7]
aWidget window() -> setWindowTitle("New Window Title")
[2]
QQuickView * view
[0]
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent