简体   繁体   English

在QML中未调用C ++类型的析构函数

[英]C++ type's destructor not called in QML

I create a Sailfish app (using latest Sailfish SDK). 我创建了一个Sailfish应用程序(使用最新的Sailfish SDK)。 I have a problem with exposing a C++ object to QML. 将C ++对象暴露给QML时遇到问题。 It inherits QSettings, 它继承了QSettings,

class Settings : public QSettings
{
    Q_OBJECT
    /**/
public:
    explicit Settings() : QSettings("Marcin Mielniczuk", "BigText") {}
    ~Settings() { qDebug() << "Dying"; }

    /**/
};

I noticed that the destructor isn't called at all. 我注意到根本没有调用析构函数。 (there's not destructor output) (没有析构函数输出)

I create the object like that: 我创建这样的对象:

import QtQuick 2.0
import Sailfish.Silica 1.0
import BigText 1.0
import "pages"

ApplicationWindow
{
    initialPage: MainPage { }
    Settings {id: settings}
}

My main.cpp is: 我的main.cpp是:

Q_DECL_EXPORT int main(int argc, char *argv[])
{
    QScopedPointer<QGuiApplication> app(Sailfish::createApplication(argc, argv));

    qmlRegisterType<Settings>("BigText", 1, 0, "Settings");

    QScopedPointer<QQuickView> view(Sailfish::createView("main.qml"));

    Sailfish::showView(view.data());

    return app->exec();
}

What am I doing wrong? 我究竟做错了什么?

/edit: Text not being printed isn't an actual problem - it's just an indicator of the problem. / edit:不打印文本不是实际问题-只是问题的指示。 The QSettings sycing in the destructor doesn't work too. 析构函数中的QSettings sycing也不起作用。

EDIT2: Please note, that ApplicationWindow in I'm using Sailfish Silica, not QtQuick.Controls, and the window is shown ok. EDIT2:请注意,我使用的是Sailfish Silica(而不是QtQuick.Controls)中的ApplicationWindow,并且窗口显示正常。 These components must be a somewhat different to the stock qt quick components. 这些组件必须与常规qt快速组件有所不同。

There's nothing inherently wrong with your logic. 您的逻辑天生没有错。 Here is a simplified version of it. 这是它的简化版本。 I can run it locally, and consistently get a Dying message on output every time the window is closed and the application terminates. 我可以在本地运行它,并且每次关闭窗口并终止应用程序时,都会在输出中始终收到一条Dying消息。

If you cannot figure it out, I suggest transforming this code into what you're doing until it fails. 如果您无法弄清楚,我建议将此代码转换为您正在做的事情,直到失败为止。

By the way, this is surely just a snippet of something larger you're doing, but at least as far as the example goes, these scoped pointers aren't doing much. 顺便说一句,这肯定只是您正在做的事情的摘要,但是至少就示例而言,这些作用域指针并没有做什么用。

main.qml main.qml

import QtQuick 2.0
import BigText 1.0

Item {
    width: 300; height: 300
    Settings {id: settings}
}

main.cpp main.cpp中

class Settings : public QSettings
{
    Q_OBJECT
    public:
    Settings() : QSettings("Marcin Mielniczuk", "BigText") {}
    ~Settings() { qDebug() << "Dying"; }

};

int main(int argc, char *argv[])
{
    QScopedPointer<QGuiApplication> app(new QGuiApplication(argc, argv));
    qmlRegisterType<Settings>("BigText", 1, 0, "Settings");
    QScopedPointer<QQuickView> view(new QQuickView());
    view->setSource(QUrl::fromLocalFile("main.qml"));
    view->show();
    return app->exec();
}

您可以尝试放置和浏览ApplicationWindow并在某个时候显式使用destroy()方法,看看会发生什么。

You cannot use QQuickView with an ApplicationWindow class. 您不能将QQuickViewApplicationWindow类一起使用。 Not only is your destructor not called, your constructor isn't either , because the loading doesn't ever succeed. 不仅是你的析构函数不叫,你的构造不是非此即彼的,因为装不永远成功。

The code below works fine under Qt 5.1.1. 下面的代码在Qt 5.1.1下可以正常工作。 Tested on both OS X 10.8 and Windows 7. 已在OS X 10.8和Windows 7上进行测试。

main.qrc main.qrc

<RCC>
  <qresource prefix="/">
    <file>main.qml</file>
  </qresource>
</RCC>

main.pro main.pro

QT       += core gui qml quick
TARGET = qml-appwin-end-18597527
TEMPLATE = app
SOURCES += main.cpp
OTHER_FILES += main.qml
RESOURCES += main.qrc

main.cpp main.cpp中

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QSettings>
#include <QQuickWindow>
#include <QtQml>
#include <QDebug>

class Settings : public QSettings
{
    Q_OBJECT
    public:
    Settings() : QSettings("Marcin Mielniczuk", "BigText") {}
    ~Settings() { qDebug() << "Dying"; }
};

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);
    QQmlApplicationEngine engine;
    qmlRegisterType<Settings>("BigText", 1, 0, "Settings");
    engine.load(QUrl("qrc:/main.qml"));
    QObject *topLevel = engine.rootObjects().value(0);
    QQuickWindow *window = qobject_cast<QQuickWindow *>(topLevel);
    window->show();
    return app.exec();
}

#include "main.moc"

main.qml main.qml

import QtQuick 2.0
import QtQuick.Controls 1.0
import BigText 1.0

ApplicationWindow {
    width: 300; height: 300
    Settings {id: settings}
}

Nothing is wrong with my code. 我的代码没有错。 It's something with the SDK. SDK就是这样。 Debugging shows 调试节目

ASSERT: "QThread::currentThread() == QCoreApplication::instance()->thread()" in file debugger/qqmldebugserver.cpp, line 576

Then the program is aborted and therefore destructor not called. 然后该程序被中止,因此不调用析构函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM