【问题标题】:Dynamic instantiation of QML objects?QML 对象的动态实例化?
【发布时间】:2013-04-14 17:50:44
【问题描述】:

我想在 QML 中绘制许多矩形。 Rectangulars (x,y) 的坐标将在 C++ 内部计算,需要传递给 QML。

我试图寻找 ListView 或 Column 或 Row 元素(带有Repeater),但这似乎无法解决问题,因为这些元素的排列方式类似于“表格”......我面临着缺乏关于此类案例的网络示例。

更具体地说:
1. 如何将我的 Rectangular 的多个坐标传递给 QML? (什么数据结构)
2. 我应该使用什么机制来显示它们?

【问题讨论】:

    标签: qt qml


    【解决方案1】:

    你可以简单地:

    import QtQuick 2.0
    
    Rectangle {
        id: root
        height: 500
        width: 500
    
        property string sc: 'import QtQuick 2.0; Rectangle {width: 20; height: 20; color: "red"; Component.onCompleted: {x = Math.random() * parent.width; y = Math.random() * parent.height;}}'
    
        Component.onCompleted: {
            for (var i = 0; i < 10; ++i) Qt.createQmlObject(sc, root, 'obj' + i);
        }
    }
    

    此代码将创建指定数量的矩形并将它们随机放置在父矩形上。

    如果必须在 C++ 中生成位置,则必须创建自定义 C++ 元素,这是一个基本示例:

    class Positioner : public QObject
    {
        Q_OBJECT
    public:
        explicit Positioner(QObject *parent = 0) : QObject(parent) {}
    
    public slots:
        QPointF getPosition() {
            return QPoint(qrand() % 500, qrand() % 500);
        }    
    };
    

    在main.cpp中注册:

    qmlRegisterType<Positioner>("TestComponent", 1, 0, "Positioner");
    

    最后使用它,这次我们使用Positioner的getPosition()C++槽:

        import QtQuick 2.0
        import TestComponent 1.0
    
        Rectangle {
            id: root
            height: 500
            width: 500
    
            Positioner {id: myPositioner}
    
            property string sc: 'import QtQuick 2.0; Rectangle {width: 20; height: 20; color: "red"; Component.onCompleted: {var pos = myPositioner.getPosition(); x = pos.x; y = pos.y;}}'
    
            Component.onCompleted: {
                for (var i = 0; i < 10; ++i) Qt.createQmlObject(sc, root, 'obj' + i);
            }
        }
    

    您还可以使用现有的 QML 文件而不是字符串,这更方便一些,因为您可以自动完成。那将是您的 TestItem 组件,只是为了好玩,它的实例会在单击时自行删除:

    import QtQuick 2.0
    
    Rectangle {
        width: 100
        height: 100
        color: "black"
    
        MouseArea {
            anchors.fill: parent
            onClicked: parent.destroy()
        }
    
        Component.onCompleted: {
            var pos = myPositioner.getPosition()
            x = pos.x
            y = pos.y
        }
    }
    

    然后在你的主 QML 文件中实例化它:

    var component = Qt.createComponent("TestItem.qml")
    component.createObject(root)
    

    如果您不想在 QML 中实例化定位器,而是在 QML 中实例化并使用单个对象,您可以执行以下操作(在 main.cpp 中):

    Positioner p;
    view.rootContext()->setContextProperty("sPositioner", &p);
    

    并在 QML 中使用:

    var pos = sPositioner.getPosition()
    

    【讨论】:

    • 我的问题似乎很粗略。我所说的“随机”是指不规则的东西,而不是定义布局的 ListView ...在您的示例中,定位器是在 QML 中实例化的。如何从 QML 视图之前存在的外部 C++ 类写入 Positioner?定位器可以是具有静态访问权限的单例吗?
    • 好吧,你不要列表,不要网格,不要随机,那么不规则到底是什么意思?
    • 添加了如何在 C++ 中实例化 Positioner 并在答案末尾的 QML 中使用。
    • 非常感谢 :) 这真的让我大开眼界。特别是用于动态 QML 实例创建的 Qt.createQmlObject。你的回答真的很全面...
    • 这确实是一个很好且完整的答案。我得到了一些关于将 C++ 逻辑输出暴露到 QML 中的好信息。谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多