Details
-
Bug
-
Resolution: Done
-
P2: Important
-
5.14.1
-
None
-
9ecc595d7185ad3d072f3d811d7aa52fc6992cca (qt/qtbase/5.14)
Description
When parent widget does not already contain any internal win id, but one of its children widgets is being destroying, => thus clears win ID => this sends QEvent::WinIdChange, and if QWIdget::winId() is requested on this event => produces a crash.
class WinIdChangeSpy : public QObject { Q_OBJECT QWidget *m_widget = nullptr; WId m_winId = 0; public: explicit WinIdChangeSpy(QWidget *widget, QObject *parent = nullptr) : QObject(parent) , m_widget(widget) , m_winId(widget->winId()) { } WId winId() const { return m_winId; } public slots: bool eventFilter(QObject *obj, QEvent *event) override { if (obj == m_widget) { if (event->type() == QEvent::WinIdChange) { m_winId = m_widget->winId(); return true; } } return false; } }; class WinIdCloseWidget : public QWidget { Q_OBJECT public: QObject *m_notifier = nullptr; QWidget *m_deleteWidget = nullptr; WinIdCloseWidget(QWidget *parent = nullptr) : QWidget(parent), m_notifier(new QObject(this)) { m_deleteWidget = new QWidget(new QWidget(this)); connect(m_notifier, &QObject::destroyed, [this] { delete m_deleteWidget; }); WinIdChangeSpy *spy = new WinIdChangeSpy(m_deleteWidget, this); m_deleteWidget->installEventFilter(spy); } }; int main() { auto widget = new WinIdCloseWidget; widget->show(); widget->windowHandle()->close(); delete widget; }