【C++/QML】C++与QML交互方法(二)

一、Cpp中调用QML方法

在Cpp中调用QML方法主要有两种途径,一是通过invokeMethod()方法,二是通过信号与槽机制。

接着上一篇内容的案例,我们在qml代码中,为Rectangle对象写一个toggleText()方法,该方法用来切换Text对象的显示状态,并且我们给Rectangle对象的objectName属性取一个名字“rectangle”(这里注意一定要加双引号),方便我们在cpp代码中找到这个对象。

接着我们希望在main.cpp代码中调用我们刚才写的qml方法-toggleText(),这里我们举例演示一下两种调用方法,首先我们需要通过engine的rootObjects()方法找到qml的根对象,然后通过objectName找到我们在qml写的rectangle对象,并用一个item指针指向它。

接下来可以通过invokeMethod(item,"toggleText")方法就可以成功调用qml中我们所写的方法了,

或者我们通过信号与槽机制,比如,我们可以创建一个timer对象,并为timer设置一个时间间隔,然后将timer的timeout()信号与qml对象的toggleText()方法连接,这样就实现了通过触发timeout()信号而调用toggleText()的效果,通过这个效果可以实现矩形内的文字出现闪烁。

二、Cpp与QML界面数据绑定

在开发过程中将后台数据在界面上进行显示是一个经常遇到的需求,在QML中提供了几种将CPP代码中的数据绑定在QML控件的方法,下面我们逐个介绍一下:

(1)绑定QStringList

qt提供了QStringList类,我们可以直接将其与QML的ListView容器进行绑定,首先我们在main.cpp文件中创建一个QStringList对象,并将它暴露给QML的上下文:

之后我们在qml中将刚暴露给上下文的myDataList绑定到ListView的mode属性上就可以在界面中显示我们的数据了:

效果如下:

(2)绑定 QList<T>

QStringList可以满足我们对于String类型数据的绑定需求,但是在开发过程中,我们往往有一些自定义数据格式绑定的需求,这时我们可以使用QList<T>来进行绑定,同样我们先写一个自定义的数据类DataObject用来演示:

之后与QStringList绑定类似,我们在main.cpp中暴露我们创建的对象,并将其绑定到qml中:

最终效果:

(3)QAbstractListModel

为了实现更好的封装效果和MVVM架构,在Qt中使用QAbstractListModel往往是最佳的实践选项,所以接下来我们讲解一下如何使用QAbstractListModel来实现后端与前端的数据绑定。

QAbstractListModel是qml中的一个基类,我们将自定义的数据结构继承自QAbstractListModel就能够实现复杂数据结构的绑定,首先我们定义一个简单的基本数据结构:

之后我们建立一个AnimalModel类,作为ViewModel(MVVM架构中的VM层),该类需要继承自QAbstractListModel,并实现几个关键的虚函数,接下来我们会着重介绍。

在qml中role扮演了后台数据与界面绑定之间重要的桥梁,role作为自定类型成员变量与qml绑定数据间的重要联系,帮助qml可以实现复杂的数据类型的绑定操作。

如上图所示,我们建立了一个枚举类型的AnimalRoles,内部定义了我们需要显示在界面的成员变量对应的Role,为了避免与Qt中标准的Role发生冲突,我们将枚举的Role从UserRole之后开始。

建立完Role之后,我们需要将Role与界面和数据类型联系起来,这里就需要实现两个方法,一个是roleNames,一个是data,这两个都是继承自QAbstractListModel中的方法。

roleNames方法中,我们建立了一个哈希表,用来给每个角色定义一个字符名称,因为enum中的变量实际是一个int值,所以我们在qml界面中需要一个角色对应的名称,方便我们在qml中进行使用,这样就完成了Role与界面之间的联系。 接下来我们建立Role与数据类型之间的联系:

我们通过实现data方法,让qml能够通过Role找到我们所需要的类型的成员变量,这样就完成了Role与数据类型之间联系的建立。

之后qml还需两个方法,一个是rowCount方法,用来获取列表的长度,一个是addItem方法用来添加数据,这两个方法实现如下:

最后在qml中我们这样绑定(removeItem是一个删除数据的方法,实现和addItem类似,就不赘述了):

最终显示效果:

  • 18
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
QML与C++交互方法主要有以下几种: 1. 使用QObject::connect()函数连接QML和C++对象的信号和槽函数,实现数据的传递和交互。 2. 使用Q_INVOKABLE宏将C++函数声明为可在QML中调用的函数。这样,QML可以直接调用C++函数,实现数据的交互。 3. 使用Q_PROPERTY宏将C++对象的属性声明为可在QML中访问的属性。这样,QML可以直接访问C++对象的属性,实现数据的交互。 4. 使用QQmlContext类将C++对象注册到QML中,并在QML中访问这些对象。这样,QML可以直接访问C++对象,实现数据的交互。 下面是一个具体的例子,展示了如何在QML中访问C++对象的属性和函数。 C++代码: ``` // MyObject.h #include <QObject> class MyObject : public QObject { Q_OBJECT Q_PROPERTY(int value READ value WRITE setValue NOTIFY valueChanged) public: explicit MyObject(QObject *parent = nullptr); int value() const; void setValue(int value); signals: void valueChanged(); private: int m_value; }; // MyObject.cpp #include "MyObject.h" MyObject::MyObject(QObject *parent) : QObject(parent) { m_value = 0; } int MyObject::value() const { return m_value; } void MyObject::setValue(int value) { if (m_value != value) { m_value = value; emit valueChanged(); } } ``` QML代码: ``` import QtQuick 2.0 Item { width: 200 height: 200 Text { text: "Value: " + myObject.value } Slider { anchors.top: text.bottom from: 0 to: 100 value: myObject.value onValueChanged: myObject.value = value } Connections { target: myObject onValueChanged: text.text = "Value: " + value } Component.onCompleted: { console.log("Value:", myObject.value) } } ``` 在这个例子中,我们创建了一个名为MyObject的C++对象,并将其注册到QML中。MyObject类有一个名为value的属性和一个名为setValue的槽函数,用于设置属性值。在QML中,我们创建一个Slider和一个Text组件,用于显示和修改MyObject的value属性。我们还使用Connections组件将MyObject的valueChanged信号与Text的text属性绑定,以使其能够自动更新。最后,在Component.onCompleted信号处理程序中,我们打印MyObject的value属性的值,以验证其已成功从C++对象传递到QML界面。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值