QQuickview删除导致应用程序崩溃

QQuickvew delete causing application to crash

Qt 5.4 在销毁 QQuickView 对象时发生崩溃。如果未设置 setQuitOnLastWindowClosed,则不会看到崩溃,默认为 trueqdoc

#include <QGuiApplication>
#include <QQuickView>
#include <QObject>
#include <QDebug>

class VDestroyer : public QObject
{
    Q_OBJECT
public:
    explicit VDestroyer(QQuickView *view, QObject *parent = 0) :
        QObject(parent), m_view(view)
    {
        // destroy m_view in 5 secs
        timerId = startTimer(5 * 1000);
    }

protected:
    void timerEvent(QTimerEvent * event)
    {
        if (event->timerId() == timerId) {
            m_view->deleteLater();
        }
    }

private :
    QQuickView *m_view;
    int timerId;
};

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);

    app.setQuitOnLastWindowClosed(false);

    QQuickView *view = new QQuickView;
    view->setSource(QUrl(QStringLiteral("qrc:/main.qml")));
    view->show();

    VDestroyer *vDestroyer = new VDestroyer(view);

    int rc = app.exec();

    qDebug() << "exiting from application!!";

    delete vDestroyer;
    return rc;
}

#include "main.moc"

完整的崩溃报告可用here.

(gdb) bt
#0  0x00007f204bc47cf4 in QBasicAtomicOps<8>::testAndSetRelaxed<QMutexData*> (
    _q_value=@0x48: <error reading variable>, expectedValue=0x0, newValue=0x1, 
    currentValue=0x7ffe453fa360)
    at ../../include/QtCore/../../src/corelib/arch/qatomic_x86.h:259
#1  0x00007f204bc47af0 in QGenericAtomicOps<QBasicAtomicOps<8> >::testAndSetAcquire<QMutexData*, QMutexData*> (currentValue=0x7ffe453fa360, newValue=0x1, expectedValue=0x0, 
    _q_value=@0x48: <error reading variable>)
    at ../../include/QtCore/../../src/corelib/thread/qgenericatomic.h:166
#2  QBasicAtomicPointer<QMutexData>::testAndSetAcquire (this=0x48, expectedValue=0x0, 
    newValue=0x1, currentValue=@0x7ffe453fa360: 0x7ffe453fa390)
    at ../../include/QtCore/../../src/corelib/thread/qbasicatomic.h:270
#3  0x00007f204bc477ab in QBasicMutex::fastTryLock (this=0x48, 
    current=@0x7ffe453fa360: 0x7ffe453fa390) at thread/qmutex.h:82
#4  0x00007f204bc46fa4 in QMutex::lock (this=0x48) at thread/qmutex.cpp:212
#5  0x00007f204be8efd9 in QCoreApplication::postEvent (receiver=0x12fd0e0, event=0x1547610, 
    priority=0) at kernel/qcoreapplication.cpp:1305
#6  0x00007f204bed0fe2 in QObject::deleteLater (this=0x12fd0e0) at kernel/qobject.cpp:2125
#7  0x0000000000401c24 in qCleanupResources_qml () at qrc_qml.cpp:81
#8  0x00007f204becf1c7 in QObject::event (this=0x1518740, e=0x7ffe453fa760)
    at kernel/qobject.cpp:1226
#9  0x00007f204be8ea82 in QCoreApplicationPrivate::notify_helper (this=0x12bfec0, 
    receiver=0x1518740, event=0x7ffe453fa760) at kernel/qcoreapplication.cpp:1052
#10 0x00007f204be8e709 in QCoreApplication::notify (this=0x7ffe453fab00, receiver=0x1518740, 
    event=0x7ffe453fa760) at kernel/qcoreapplication.cpp:997
#11 0x00007f204c27bb52 in QGuiApplication::notify (this=0x7ffe453fab00, object=0x1518740, 
    event=0x7ffe453fa760) at kernel/qguiapplication.cpp:1528

项目 https://github.com/shrkamat/QlmResourceCleanup.git

应该允许使用应用程序事件循环 运行 销毁 QQuickView,在我看来这像是一个 Qt 错误。

QTimer 默认是重复的,http://doc.qt.io/qt-5/qtimer.html#singleShot-prop这会导致删除已经销毁的对象。