退出时删除 QQuickView 会导致 Qt 应用程序冻结

Posted

技术标签:

【中文标题】退出时删除 QQuickView 会导致 Qt 应用程序冻结【英文标题】:Deleting QQuickView on exit cause Qt application to freeze 【发布时间】:2014-06-04 18:40:03 【问题描述】:

我在 Qt 5.3 中建立了一个死锁。如何正确修复?没有丑陋的修复(不要删除 qquickview *)

我有一个指向QQuickView 的单例。当我需要关闭我的应用程序时,我会调用QGuiApplication::quit() 并尝试在singlenot 的析构函数中释放QQuickView *。结果 - 应用程序冻结。

示例:

test.qml

import QtQuick 2.1

Rectangle

    id: root;
    color: "black";

    signal quit();
    Component.onDestruction: quit();

ma​​in.cpp

#include <QGuiApplication>
#include <QQuickView>
#include <QQuickItem>
#include <QPointer>


struct Singleton

    QPointer< QQuickView > w;
    static Singleton inst;

    int run( int argc, char *argv[] )
    
        QGuiApplication a( argc, argv );
        w = new QQuickView();

        QObject::connect( w, &QQuickView::statusChanged, [=]()
        
            QObject::connect( w->rootObject(), SIGNAL( quit() ), qApp, SLOT( quit() ) );
         );

        w->setSource( QUrl( "qrc:/test.qml" ) );
        w->setResizeMode( QQuickView::SizeRootObjectToView );
        w->show();

        a.exec();

        return 0;
    

    ~Singleton()
    
        delete w;   // Comment this to fix bug
    

;

Singleton Singleton::inst;


int main(int argc, char *argv[] )

    Singleton::inst.run( argc, argv );
    return 0;

附: C++0x 用于简化代码。在 C++03 编译器上的结果相同。

【问题讨论】:

如果你把delete w;放在a.exec();之后呢? 似乎是已知问题:bugreports.qt-project.org/browse/QTBUG-36115 如果我将delete w 放在a.exec() 之后,那么一切正常。但似乎它是 MS CRT 的功能(在退出 main() 时终止应用程序)。 嵌套connects的目标是什么? @Orient 等到 QML 被加载并创建根对象。 【参考方案1】:

这是 Qt 中的 bug。从 5.4 版本开始修复。

【讨论】:

以上是关于退出时删除 QQuickView 会导致 Qt 应用程序冻结的主要内容,如果未能解决你的问题,请参考以下文章

如何将 Qt 鼠标事件转发到 QQuickView?

带有 QQuickView 的 QML 信号 QT 插槽

使用脚本运行 Qt 程序会导致程序在退出时重新启动

Qt:隐藏然后显示 QQuickView 防止未来的鼠标事件

将 QML(QQuickView) 添加到现有 UI

QQuickView 新删除类型不匹配