QQuickview删除导致应用程序崩溃
QQuickvew delete causing application to crash
Qt 5.4 在销毁 QQuickView 对象时发生崩溃。如果未设置 setQuitOnLastWindowClosed
,则不会看到崩溃,默认为 true
、qdoc。
#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这会导致删除已经销毁的对象。
Qt 5.4 在销毁 QQuickView 对象时发生崩溃。如果未设置 setQuitOnLastWindowClosed
,则不会看到崩溃,默认为 true
、qdoc。
#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这会导致删除已经销毁的对象。