使用组件时将c++绑定到QML代码

Binding C++ to QML code when using Components

本文关键字:绑定 QML 代码 c++ 组件      更新时间:2023-10-16

——编辑url并将动态部分更改为可编译的东西----(使用Qt 5.3)我试着创建一个紧凑的样本,但它仍然太大,不能在这里单独发布所有文件,所以我添加了一个链接到"上传"。由于我无法在此附上zip文件:-(()(警告,垃圾链接和/或等待时间,你推荐任何更好的文件共享网站吗?

这是一个链接到"bindtest.zip"通过uploaded.com,小心垃圾邮件/丑陋的图片:

http://ul.to/lqemy5jx

好吧,我会尽量把文件的精华贴在这里:

我尝试在c++中创建一个包含StringList和索引的简单类。我实例化了这个类的两个对象,并通过"setContextProperty"

应该在QML中用于初始化ListView并与之同步。因此,当用户在QML中更改索引时,应该通知c++,反之亦然。

所以当我创建两个组件qml文件使用硬连线名称设置在"setContextProperty"它似乎工作得很好。

但是对于我的生命,我不能创建一个单一的组件文件,并将数据对象作为参数传递给它,我只是不知道如何做到这一点,尽管我尝试过。

我的"最终"目标列表动态创建QML对象并传递DataObject给它,这也不起作用:-(

)

来了,我的示例项目的代码片段:

声明我的简单类(DataObject.h)

#ifndef DATAOBJECT_H
#define DATAOBJECT_H
#include <QObject>
#include <QDebug>
class DataObject : public QObject
{
    Q_OBJECT
    Q_PROPERTY( int index MEMBER m_index NOTIFY indexChanged )
public slots:
    int count() const { return m_Elements.count(); }
    QString at(int idx) const { return m_Elements.at(idx); }
public:
    void setIndex(int theInt) { m_index = theInt; }
signals:
    void indexChanged(int);
public: // too lazy to write accessors for this sample, so make it public
    QStringList m_Elements;
private:
    int m_index;
};
#endif // DATAOBJECT_H

在main.cpp中注册:

qmlRegisterType<DataObject>("bindtestTypes", 1, 0, "DataObject");

下面是"dialog.cpp"中初始化并公开两个数据对象的部分:

//preparing first list
m_firstDO.m_Elements = QStringList() << "A" << "B" << "C" << "D";
m_firstDO.setIndex(0);
//preparing second list
m_secondDO.m_Elements = QStringList() << "a" << "b" << "c" << "d";
m_secondDO.setIndex(3);
//publish the 2 Dataobjects
m_engine.rootContext()->setContextProperty( "cppDataList_1", &m_firstDO);
m_engine.rootContext()->setContextProperty( "cppDataList_2", &m_secondDO);

下面是QML文件"ShowLists"。qml",它应该简单地显示两个列表在彼此的顶部,我评论了两个不工作的方法,我喜欢工作,特别是动态的:

import QtQuick 2.2进口QtQuick。窗口2.1导入bindtestTypes 1.0

Window {
    visible: true
    width: 200
    height: 400
    Rectangle{
        anchors.fill: parent
//dynamic: does not work :-(
// need to click on it to create it
//        Rectangle{
//            id:upperList
//            anchors.top: parent.top;
//            anchors.left: parent.left
//            width:200
//            height:200
//            MouseArea{
//                anchors.fill: parent
//                onClicked: {
//                    var component = Qt.createComponent("SimpleList.qml");
//                    var dyncbb = component.createObject(parent, {"theDO": cppDataList_1});
//                }
//            }
//        }
//        Rectangle{
//            id:lowerList
//            anchors.bottom: parent.bottom;
//            anchors.left: parent.left
//            width:200
//            height:200
//            MouseArea{
//                anchors.fill: parent
//                onClicked: {
//                    var component = Qt.createComponent("SimpleList.qml");
//                    var dyncbb = component.createObject(parent, {"theDO": cppDataList_2});
//                }
//            }
//        }

//static: would not be my first choice but isnt working anyways...
//        SimpleList {
//            id:upperList
//            property DataObject theDO: cppDataList_1
//            anchors.top: parent.top;
//            anchors.left: parent.left
//        }
//        SimpleList {
//            id:lowerList
//            property DataObject theDO: cppDataList_2
//            anchors.bottom: parent.bottom;
//            anchors.left: parent.left
//        }
//hardwired works, but its not workable for my rather complex project...
        SimpleList1 {
            id:upperList
            anchors.top: parent.top;
            anchors.left: parent.left
        }
        SimpleList2 {
            id:lowerList
            anchors.bottom: parent.bottom;
            anchors.left: parent.left
        }
    }
}

这是第一个硬连接的SimpleList1。QML工作良好,以及第二个:

import QtQuick 2.2
    ListView {
        id: list_view
        width: 200
        height: 200
        currentIndex: cppDataList_1.index
        model: cppDataList_1.count()
        delegate: Rectangle {
            height: 20
            width: 200
            Text { text: cppDataList_1.at(index); color: (list_view.currentIndex === index)?"red":"black" }
            MouseArea{ anchors.fill: parent; onClicked: list_view.currentIndex = index }
        }
        onCurrentIndexChanged: cppDataList_1.index = currentIndex;
    }

这是"SimpleList"。Qml ",我似乎无法开始工作:

import QtQuick 2.2
import bindtestTypes 1.0
Rectangle {
    ListView {
        id: list_view
        property DataObject theDO
        width: 200
        height: 200
        currentIndex: theDO.index
        model: theDO.count()
        delegate: Rectangle {
            height: 20
            width: 200
            Text { text: theDO.at(index); color: (list_view.currentIndex === index)?"red":"black" }
            MouseArea{ anchors.fill: parent; onClicked: list_view.currentIndex = index }
        }
        onCurrentIndexChanged: theDO.index = currentIndex
    }
}

那么,你们谁能帮我解决这个问题??

如果你敢跟随上传的链接并运行我的示例,你可以看到更多的故障。它显示2个窗口,一个QQQuickWIndow和一个Widget。在Widget中,我可以像在QML窗口中一样更改索引。起初它们是同步的,但随后QML窗口不再通过更改小部件中的索引来更新,我希望这是一个小故障,而不是我犯的另一个一般错误。

问候,谢谢你的帮助!

Nils

啊,我发现了问题,我做了一个非常简单的错误:

我想在SimpleList组件中设置的属性必须在根对象中,所以不要这样:

Rectangle {
    ListView {
        id: list_view
        property DataObject theDO
...

必须这样做:

Rectangle {
    property DataObject theDO
    ListView {
        id: list_view
...

哇,这是一个(看似)复杂问题的简单解决方案。

问候,

Nils