[Interest] Handling QObject auto-deletion and signals emitted from destructors
Neil Williams
neil at copycopy.cc
Tue Sep 1 17:06:58 CEST 2015
Below is a example program which will crash when the widget is closed.
This setup replicates the QWebview behaviour where it will emit the
loadFinished signal from inside the destructor if a page is loading.
I am wondering if anyone can suggest a clean way of handling this sort of
case, where a sibling may have been deleted but is referenced in a
connected slot of a non-deleted object.
I have considered:
1. Always using QPointer and check for object validity before accessing in
the slot. This seems like it would be somewhat tedious.
2. Using the 'context' param of QObject::connect override and splitting the
current slot into multiple smaller slots that only access a single param,
e.g:
connect(webview, &QWebView::loadFinished, ok_widget, [this] (bool ok) {
ok_widget->setVisible(ok);
});
connect(webview, &QWebView::loadFinished, fail_widget, [this] (bool ok) {
fail_widget->setVisible(!ok);
});
This requires more boilerplate and may not be possible for more
complex slots which need to access multiple objects.
3. Call to QObject::disconnect in the containing class destructor.
This does feel a little bit like I am micro-managing the connections
which would be nice to avoid.
4. Switch to manual memory management of the widgets so I can control
destruction order.
At the moment I am considering either 1, 3 or 4 but I would appreciate any
other views/opinions/suggestions.
Thanks.
#ifndef WIDGET_H
#define WIDGET_H
#include <QDebug>
#include <QtWidgets>
#include <QWebView>
#include <QPointer>
class QWebView;
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget() {
QVBoxLayout* layout = new QVBoxLayout();
webview = new QWebView();
ok_widget = new QWidget();
fail_widget = new QWidget();
connect(webview, &QWebView::destroyed, [this] () {
// replicate loadFinished being fired during qwebview/webpage destruction
emit webview->loadFinished(false);
});
connect(webview, &QWebView::loadFinished, this, &Widget::onLoadFinished);
layout->addWidget(ok_widget);
layout->addWidget(fail_widget);
layout->addWidget(webview);
setLayout(layout);
}
~Widget() {
qDebug() << "Window destroyed";
}
private slots:
void onLoadFinished(bool ok) {
ok_widget->setVisible(ok);
fail_widget->setVisible(!ok);
}
private:
QWebView* webview;
QWidget* ok_widget;
QWidget* fail_widget;
};
#endif // WIDGET_H
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20150901/21eaa9c2/attachment.html>
More information about the Interest
mailing list