【问题标题】:How to create QML object within a singleton?如何在单例中创建 QML 对象?
【发布时间】:2016-02-20 05:42:36
【问题描述】:

我在MyQMLObject.qml 下定义了一个QML 对象。此 QML 文件如下所示:

import QtQuick 2.4

Item {
  id: rootItem
  implicitWidth: LayoutUtils.maxImplicitWidth(children)
  implicitHeight: LayoutUtils.maxImplicitHeight(children)

  Text {
    id: text1
  }
  Text {
    id: text2
  }
  // ...
  Text {
    id: textN
  }
}

文本是在应用程序启动时动态添加的。为每种语言添加不同的文本,rootItem 的宽度因所选语言而异。我想以某种方式仅在应用程序启动时创建一次MyQMLObject,甚至不将其可视化并将其实际宽度保存在一个单例中,这样我就可以在整个代码中重用该值,而无需多次创建MyQMLObject。我怎样才能做到这一点?

现在我有一个单例 QML 文件,其中包含一个 QtObject,其中包含一些常量值。我可以在这个单例QtObject 中以某种方式创建MyQMLObject 的实例吗?

我的单身Style.qml 看起来像这样:

pragma Singleton

import QtQuick 2.4

QtObject {
  readonly property int maxWidth: 400
  // ...
}

【问题讨论】:

  • 是否必须使用 QML 来计算文本大小?
  • 不一定。谢谢你的替代建议!
  • 为什么不直接使用text1.paintedWidth
  • @sk2212:我只用文本简化了问题,但总的来说,我希望它也能处理更复杂的 GUI 项目。

标签: qt qml qt5


【解决方案1】:

首先,如果可能,您可以使用Column 而不是手动计算最大宽度:

MyQMLObject.qml

import QtQuick 2.4

Column {
    Text {
        text: "blah"
    }
    Text {
        text: "blahblah"
    }
}

您可以使用dynamic object creation 来创建临时的Column 项:

Style.qml

pragma Singleton

import QtQuick 2.4

QtObject {
    readonly property int maxWidth: {
        var component = Qt.createComponent("qrc:/MyQMLObject.qml");
        if (component.status === Component.Error) {
            console.error(component.errorString());
            return 0;
        }

        return component.createObject().width;
    }
}

ma​​in.qml

import QtQuick 2.5
import QtQuick.Window 2.2

import App 1.0

Window {
    visible: true

    Component.onCompleted: print(Style.maxWidth)
}

那么,register the singleton

ma​​in.cpp

#include <QtGui>
#include <QtQml>

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

    qmlRegisterSingletonType(QUrl("qrc:///Style.qml"), "App", 1, 0, "Style");

    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

    return app.exec();
}

但是,请注意,可以通过从 C++ 计算最大宽度来改进这种方法,从而无需构建一个项目只是为了将其丢弃。下班this example:

#include <QtGui>
#include <QtQml>

class Style : public QObject
{
    Q_OBJECT
    Q_PROPERTY(int maxWidth READ maxWidth CONSTANT)

public:
    Style(QObject* parent = 0) :
        QObject(parent),
        mMaxWidth(0)
    {
        QFontMetrics fontMetrics(qApp->font());
        // Here is where you'd fetch the text...
        QStringList dummyText;
        dummyText << "blah" << "blahblah";
        foreach (const QString &string, dummyText) {
            const int width = fontMetrics.boundingRect(string).width();
            if (width > mMaxWidth)
                mMaxWidth = width;
        }
    }

    int maxWidth() const
    {
        return mMaxWidth;
    }

private:
    int mMaxWidth;
};

static QObject *singletonTypeProvider(QQmlEngine *, QJSEngine *)
{

    Style *style = new Style();
    return style;
}

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

    qmlRegisterSingletonType<Style>("App", 1, 0, "Style", singletonTypeProvider);

    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

    return app.exec();
}

#include "main.moc"

它使用QFontMetrics 来计算width

main.qml 保持不变。

【讨论】:

  • 哇,感谢 Mitch 的详细回答,也感谢您提出替代方案!马上就试一试。
  • 我正在阅读qmldir,因为这对我来说更可取。看起来你不需要使用qmlRegisterSingletonType。它可以省略,因为没有它我无法让它工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-02-16
  • 1970-01-01
  • 2015-09-11
  • 1970-01-01
  • 2014-07-18
  • 2020-04-16
  • 1970-01-01
相关资源
最近更新 更多