Ver código fonte

Fix Qt designer crash when dropping spinbox in ctkCollapsibleGroupBox

ctkCollapsibleGroupBox (and ctkCollapsibleButton) were setting the visibility
of the newly added child spinbox to ON (at backtrace line 5).
As a side effect, QAbstractSpinBox::setLineEdit() was calling updateEdit()
which was trying to access some RTTI information that is not yet available
(because it was still in the spinbox constructor).

See below the backtrace:
#0  0x00007ffff6d78d50 in typeinfo for QAbstractSpinBox () from /home/julien/work/qt/qt-4.8.5/lib/libQtGui.so.4
#1  0x00007ffff65bb3b8 in QDoubleSpinBoxPrivate::textFromValue (this=0x1768890, f=...) at widgets/qspinbox.cpp:1279
#2  0x00007ffff64f9449 in QAbstractSpinBoxPrivate::updateEdit (this=0x1768890) at widgets/qabstractspinbox.cpp:1736
#3  0x00007ffff64f4e83 in QAbstractSpinBox::setLineEdit (this=0x1768860, lineEdit=0x1741840) at widgets/qabstractspinbox.cpp:686
#4  0x00007ffff64f87b9 in QAbstractSpinBoxPrivate::init (this=0x1768890) at widgets/qabstractspinbox.cpp:1558
#5  0x00007ffff64f401a in QAbstractSpinBox::QAbstractSpinBox (this=0x1768860, dd=..., parent=0x16bb7d0) at widgets/qabstractspinbox.cpp:152
#6  0x00007ffff65b8fae in QDoubleSpinBox::QDoubleSpinBox (this=0x1768860, parent=0x16bb7d0) at widgets/qspinbox.cpp:603
#7  0x00007ffff7283ab2 in qdesigner_internal::WidgetFactory::createWidget (this=0x8df9f0, widgetName=..., parentWidget=0x16bb7d0) at uilib/widgets.table:75
[...]
#41 0x00007ffff569706e in QEventLoop::exec (this=0x1489ac0, flags=...) at kernel/qeventloop.cpp:204
#42 0x00007ffff60d7438 in QDragManager::drag (this=0x1731a20, o=0x12b1780) at kernel/qdnd_x11.cpp:2028
#43 0x00007ffff6035bc1 in QDrag::exec (this=0x12b1780, supportedActions=..., defaultDropAction=Qt::CopyAction) at kernel/qdrag.cpp:284
[...]
#56 0x00007ffff66b53cd in QAbstractItemView::pressed (this=0x12b5f00, _t1=...) at .moc/debug-shared/moc_qabstractitemview.cpp:340
#57 0x00007ffff66a8b79 in QAbstractItemView::mousePressEvent (this=0x12b5f00, event=0x7fffffffcf90) at itemviews/qabstractitemview.cpp:1693
[...]
#68 0x00007ffff6024b9d in QCoreApplication::sendSpontaneousEvent (receiver=0x12b5f40, event=0x7fffffffcf90) at ../../include/QtCore/../../src/corelib/kernel/qcoreapplication.h:234
#69 0x00007ffff601eb61 in QApplicationPrivate::sendMouseEvent (receiver=0x12b5f40, event=0x7fffffffcf90, alienWidget=0x12b5f40, nativeWidget=0x95b2e0, buttonDown=0x7ffff6dbaa58,
    lastMouseReceiver=..., spontaneous=true) at kernel/qapplication.cpp:3171
[...]
#78 0x00007ffff5696ee4 in QEventLoop::processEvents (this=0x7fffffffddf0, flags=...) at kernel/qeventloop.cpp:149
#79 0x00007ffff569706e in QEventLoop::exec (this=0x7fffffffddf0, flags=...) at kernel/qeventloop.cpp:204
#80 0x00007ffff569a0b8 in QCoreApplication::exec () at kernel/qcoreapplication.cpp:1221
#81 0x00007ffff601f776 in QApplication::exec () at kernel/qapplication.cpp:3823
#82 0x0000000000432a07 in main (argc=1, argv=0x7fffffffdfa8) at main.cpp:57

Closes #349
Julien Finet 11 anos atrás
pai
commit
36f72607d9

+ 7 - 1
Libs/Widgets/ctkCollapsibleButton.cpp

@@ -141,7 +141,13 @@ void ctkCollapsibleButtonPrivate::setChildVisibility(QWidget* childWidget)
     visible = false;
     }
 
-  childWidget->setVisible(visible);
+  // Setting Qt::WA_WState_Visible to true during child construction can have
+  // undesirable side effects.
+  if (childWidget->testAttribute(Qt::WA_WState_Created) ||
+      !visible)
+    {
+    childWidget->setVisible(visible);
+    }
 
   // setVisible() has set the ExplicitShowHide flag, restore it as we don't want
   // to make it like it was an explicit visible set because we want

+ 9 - 3
Libs/Widgets/ctkCollapsibleGroupBox.cpp

@@ -93,7 +93,7 @@ public:
   /// who is changing children's visibility.
   bool     ForcingVisibility;
   /// Sometimes the creation of the widget is not done inside setVisible,
-  /// as we need to do special processing the first time the button is
+  /// as we need to do special processing the first time the groupBox is
   /// setVisible, we track its created state with the variable
   bool     IsStateCreated;
 
@@ -163,11 +163,17 @@ void ctkCollapsibleGroupBoxPrivate::setChildVisibility(QWidget* childWidget)
     visible = false;
     }
 
-  childWidget->setVisible(visible);
+  // Setting Qt::WA_WState_Visible to true during child construction can have
+  // undesirable side effects.
+  if (childWidget->testAttribute(Qt::WA_WState_Created) ||
+      !visible)
+    {
+    childWidget->setVisible(visible);
+    }
 
   // setVisible() has set the ExplicitShowHide flag, restore it as we don't want
   // to make it like it was an explicit visible set because we want
-  // to allow the children to be explicitly hidden by the user.
+  // to allow any children to be explicitly hidden by the user.
   if ((!childWidget->property("visibilityToParent").isValid() ||
       childWidget->property("visibilityToParent").toBool()))
     {