Details
-
Bug
-
Resolution: Done
-
P2: Important
-
4.5.3
-
None
-
f8fb064d6b2ad55c66ce1a481e7f829278051fcb
Description
//
// Test program that demonstrates NULL Qt widgets.
//
// When a widget is destroyed it's children are also destroyed, but during
// that process the child list is maintained with the destroyed widgets set
// to NULL; here is some abbreviated code from qobject.cpp:
//
// void QObjectPrivate::deleteChildren()
// {
// ...
// for (int i = 0; i < children.count(); ++i)
// children.clear();
// ...
// }
//
// A situation can arise where during the destruction process an event is
// propagated to these NULL children. In Qt 4.3.1, a warning message is
// printed to this effect:
//
// QApplication::notify: Unexpected null receiver
//
// In Qt 4.5.3 this behavior has changed and the NULL children may be
// de-referenced causing a segmentation fault.
//
// This test program creates a top-level widget with two children. When you
// close the top-level widget the children are destroyed, and the second
// child attempts to open a modal dialog box in it's destructor. This modal
// dialog causes an event to be propagated to the first child widget which has
// already been destroyed.
//
#include <QApplication> #include <QHBoxLayout> #include <QMessageBox> #include <QWidget> #include <iostream> // // Utility function to print out child widget pointers. // void printChildren(QObject* in) { const QObjectList children = in->children(); for (int i = 0; i < children.size(); ++i) std::cout << "child [" << i << "] = " << children[i] << std::endl; } // // Widget base class. // class BaseWidget : public QWidget { public: QSize sizeHint() const { return QSize (100, 100); } }; // // First widget. // class Widget1 : public BaseWidget { public: ~Widget1() { std::cout << "Widget1::~Widget1()" << std::endl; printChildren(parent()); } }; // // Second widget. This widget spawns a modal dialog in it's destructor. // class Widget2 : public BaseWidget { public: ~Widget2() { std::cout << "Widget2::~Widget2()" << std::endl; printChildren(parent()); QMessageBox().exec(); } }; int main(int argc, char** argv) { QApplication app (argc, argv); // // Create the window. // QWidget* window = new QWidget; window->setAttribute (Qt::WA_DeleteOnClose); // // Create the widgets. // Widget1* widget1 = new Widget1; Widget2* widget2 = new Widget2; // // Layout the widgets. // QHBoxLayout* layout = new QHBoxLayout; window->setLayout (layout); layout->addWidget (widget1); layout->addWidget (widget2); // // Start the application. // printChildren (window); window->show(); return app.exec(); }