【问题标题】:Create a QML component from string从字符串创建 QML 组件
【发布时间】:2015-01-31 22:28:30
【问题描述】:

可以使用Qt.createComponent(filename)从文件创建 QML 组件

可以使用Qt.createQmlObject(string)从字符串创建QML对象

可以通过Component {...}从代码创建QML组件

但是可以从字符串创建 QML 组件吗?我的意思是没有为了使用Qt.createComponent(filename)而努力将其保存为临时文件?

编辑:澄清一下,我已经有了这个示例表单中的组件:

import QtQuick 2.0

Rectangle {
     width: 100
     height: 100
     color: "red"
}

所以我需要从该字符串创建一个组件而不实例化它。我不能简单地将字符串包装在 "Component {" + string + "}" 中,因为不能在组件内声明导入。一种解决方案是使用复杂的解析将组件插入到第一个元素之前和导入之后,但这并不是最优雅的解决方案。

【问题讨论】:

  • 您自己说要从带有Qt.createQmlObject(string) 的字符串创建组件。那么你的问题是什么?
  • @folibis - 不,再次检查,我说的“QML 对象”与“QML 组件”不同,该组件是对象的原型,但您不能使用对象在需要组件的地方。
  • 如果您不介意使用 C++,您可以创建自己的在内部使用 QQmlComponent 的组件,因为该类具有 setData() 函数。您可以将此自定义组件类公开给将调用转发给 setData() 的 QML,或者将数据属性创建为字符串。
  • @Mitch - 这确实有效,您应该将其发布为答案。但是,这又引发了另一个问题——如何自动管理组件的生命周期stackoverflow.com/questions/27315030/…
  • 发布了答案。顺便说一句,这里有一个建议将其添加到 Qt:bugreports.qt.io/browse/QTBUG-26278

标签: string qt components qml qtquick2


【解决方案1】:

使用Qt.createQmlObject(string)。它创建一个对象,而不是原型。

Window {
    id: mainWindow
    visible: true
    width: 600
    height: 400
    Component.onCompleted: {
        var str = '
        import QtQuick 2.3;
        Component {
            Text {
                text: "Hello, world!";
                anchors.fill: parent;
                horizontalAlignment: Text.AlignHCenter;
                verticalAlignment: Text.AlignVCenter;
            }
        }';
        var component = Qt.createQmlObject(str,mainWindow);
        var object = component.createObject(mainWindow);
    }
}

【讨论】:

  • 我需要从字符串创建一个组件,而不是一个对象。
  • 问题是我已经有了导入的组件字符串,但没有包装Component。我不能在Component { 前面加上},因为这会破坏代码,不能在Component 中完成导入
【解决方案2】:

差不多 7 年后,我遇到了自己做这件事的需要,所以我想我会详细说明我在这个问题上留下的评论。

对于我的用例,单例做得更好。您可以像这样在 QML 中使用它:

import MyModule 1.0

// ...

Loader {
    sourceComponent: QmlComponentCreator.createComponent("import QtQuick 2.0; Item {}")
}

C++ 实现如下。

QmlComponentCreator.h

#ifndef QMLCOMPONENTCREATOR_H
#define QMLCOMPONENTCREATOR_H

#include <QObject>
#include <QQmlComponent>

class QmlComponentCreator : public QObject
{
    Q_OBJECT

public:
    QmlComponentCreator() = default;

    Q_INVOKABLE QQmlComponent *createComponent(const QByteArray &data) const;
};

#endif // QMLCOMPONENTCREATOR_H

QmlComponentCreator.cpp

#include "QmlComponentCreator.h"

#include <QtQml>

QQmlComponent *QmlComponentCreator::createComponent(const QByteArray &data)
{
    QQmlComponent *component = new QQmlComponent(qmlEngine(this));
    QQmlEngine::setObjectOwnership(component, QQmlEngine::JavaScriptOwnership);
    component->setData(data, QUrl());
    if (component->isError())
        qmlWarning(this) << "Failed to create component from the following data string:\n" << data;
    return component;
}

ma​​in.cpp 中的某处,或您注册类型的任何位置:

qmlRegisterSingletonType<QmlComponentCreator>("MyModule", 1, 0, "QmlComponentCreator",
    [](QQmlEngine *, QJSEngine *) { return new QmlComponentCreator; });

【讨论】:

    猜你喜欢
    • 2016-12-02
    • 1970-01-01
    • 1970-01-01
    • 2016-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多