1

我创建了一个 Sailfish 应用程序(使用最新的 Sailfish SDK)。我在将 C++ 对象暴露给 QML 时遇到问题。它继承了 QSettings,

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

    /**/
};

我注意到根本没有调用析构函数。(没有析构函数输出)

我这样创建对象:

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

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

我的 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();
}

我究竟做错了什么?

/edit:未打印的文本不是实际问题 - 它只是问题的一个指标。析构函数中的 QSettings 同步也不起作用。

EDIT2:请注意,我使用 Sailfish Silica 中的 ApplicationWindow,而不是 QtQuick.Controls,并且窗口显示正常。这些组件必须与库存的 qt 快速组件有所不同。

4

4 回答 4

2

你的逻辑本质上没有错。这是它的简化版本。我可以在本地运行它,并且每次关闭窗口并且应用程序终止时始终在输出上收到Dying消息。

如果您无法弄清楚,我建议将此代码转换为您正在执行的操作,直到它失败为止。

顺便说一句,这肯定只是您正在做的更大事情的一小部分,但至少就示例而言,这些作用域指针并没有做太多事情。

main.qml

import QtQuick 2.0
import BigText 1.0

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

主文件

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();
}
于 2013-09-03T20:58:09.697 回答
1

您不能QQuickViewApplicationWindow课程一起使用。不仅你的析构函数没有被调用,你的构造函数也没有被调用,因为加载永远不会成功。

下面的代码在 Qt 5.1.1 下运行良好。在 OS X 10.8 和 Windows 7 上测试。

主.qrc

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

主程序

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

主文件

#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

import QtQuick 2.0
import QtQuick.Controls 1.0
import BigText 1.0

ApplicationWindow {
    width: 300; height: 300
    Settings {id: settings}
}
于 2013-09-04T18:44:18.430 回答
1

我的代码没有任何问题。这与 SDK 有关。调试显示

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

然后程序被中止,因此不调用析构函数。

于 2013-09-08T08:12:31.427 回答
1

您可以尝试放置并 id yo tour ApplicationWindow 并在某个时候明确使用 destroy() 方法,看看会发生什么。

于 2013-09-04T16:06:04.937 回答