Qml与C++交互4:C++信号与Qml的槽函数的连接

请添加图片描述
更多资讯、知识,微信公众号搜索:“上官宏竹”。


使用场景

比如在C++中更改某些数据,实时更新到UI界面中。

整体思路

C++中建立一个信号并发送,在Qml中使用Connections建立一个对应的响应槽函数,当C++发送信号时,触发Qml对应的槽函数。

1、建立C++信号

首先我们声明一个信号如下,然后在点击的槽函数中将信号发出去。

{
signals:
    void myClassInfoSignal();	// C++的信号名
}

void MyClass::myRectSlot(int count)
{
    qDebug()<<__FUNCTION__<<" count: "<<count;

    emit myClassInfoSignal();	// 发射信号
}

2、C++实例注册到qml

使用qmlRegisterSingletonInstance方法或者engine.rootContext()->setContextProperty的方法,将C++中的实例注册到qml中。

注意:在Windows系统上使用engine.rootContext()->setContextProperty的方法,会出现如下的告警错误:

QML Connections: Detected function "onMyClassInfoSignal" in Connections element. This is probably intended to be a signal handler but no signal of the target matches the name.
ReferenceError: MyclassApi is not defined

大家可以改用qmlRegisterSingletonInstance方法进行注册,在import注册号的模块名后,对应的告警会消失;或者先进行属性设置即先调用engine.rootContext()->setContextProperty方法,然后再加载qml文件。

engine.load(url);

auto root = engine.rootObjects();
auto button = root.first()->findChild<QObject*>("mybutton");

3、qml中建立槽函数

Connections类型

简单说下Connections类型。Connections分为两部分:一个是target属性,表示发出信号的对象。另一个是对应信号的槽函数。
在这里插入图片描述
上图表示targetA发出两个信号asignal1和asignal2,然后对应的Connections可以写作如下,来接收处理这两个信号:

Connections {
	target: targetA;
	function onAsignal1() {
		// 信号处理槽函数
	}
	function onAsignal2() {
		// 信号处理槽函数
	}	
}

建立槽函数

我们使用Connections类型,来达到C++信号和Qml槽函数的自动连接处理。Connections类型中的target : Object,表示与来自哪一个对象的信号连接。而槽函数的命名,则需要以小写的on开头,并连接C++的信号函数名字,且第一个字母需要大写。整个槽函数如下:

Connections {
	target: MyclassApi	// 已注册的C++中的对象名字

	// 槽函数 on + C++的信号名称(首字母大写)
	function onMyClassInfoSignal() {
		console.log("haha C++ signal is coming...")
	}
}

运行结果

MyClass::myRectSlot  count:  1
qml: haha C++ signal is coming...
MyClass::myRectSlot  count:  2
qml: haha C++ signal is coming...

使用属性

在C++类中,可以使用Q_PROPERTY属性定义读写接口以及属性变化的信号,当这个信号与qml的槽函数连接时,需要注意,如果是使用QtCreator自动生成的接口,那么READ接口不能返回引用,否则在qml中调用这个READ接口的返回值是未定义;并且接口定义前需要加上Q_INVOKABLE,否则qml无法识别这个接口。

比如这个属性定义:Q_PROPERTY(QString key READ getKey WRITE setKey NOTIFY keyChanged),自动生成的READ接口如下:

// 头文件声明
const QString& getKey() const;

// 源文件实现
const QString& MyLogic::getKey() const
{
    return m_key;
}

需要将上述的定义和实现更改为:

// 头文件声明
Q_INVOKABLE const QString getKey() const;

// 源文件实现
const QString MyLogic::getKey() const
{
    return m_key;
}

完整实现可以微信搜索公众号:“上官宏竹”,或者扫下面的二维码,关注并回复:“qml_4”,获取资源链接。有任何疑问也可以公众号里留言咨询。


更多资讯、知识,微信公众号搜索:“上官宏竹”。
请添加图片描述

  • 2
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
QMLC++ 交互的过程一般分为以下几个步骤: 1. 定义 C++ 类并注册到 QML 中 你需要在 C++ 中定义一个类,该类封装了你想要实现的功能。同时,你需要使用 `qmlRegisterType` 函数将该类注册到 QML 中,以便在 QML 中使用该类。 例如,你可以定义一个名为 `MyClass` 的类,并将其注册到 QML 中: ```cpp class MyClass : public QObject { Q_OBJECT public: Q_INVOKABLE int myFunction(int arg) { // 实现你的功能 } }; qmlRegisterType<MyClass>("com.example", 1, 0, "MyClass"); ``` 在上面的代码中,`Q_INVOKABLE` 用于声明 `myFunction` 函数可从 QML 中调用,`qmlRegisterType` 函数用于将 `MyClass` 类注册到 QML 中。`"com.example"` 表示注册的命名空间,`1` 和 `0` 表示主版本号和次版本号,`"MyClass"` 是在 QML 中使用的类名。 2. 在 QML 中使用 C++ 类 在 QML 中使用 C++ 类时,你需要使用 `import` 语句导入该类所在的命名空间。然后,你可以通过该命名空间来访问该类。例如: ```qml import com.example 1.0 MyClass { id: myClass } Button { onClicked: { var result = myClass.myFunction(42) // 处理返回值 } } ``` 在上面的代码中,`import` 语句用于导入 `com.example` 命名空间,`MyClass` 用于创建一个 `MyClass` 实例,`id` 属性用于设置实例的标识符,`Button` 用于创建一个按钮,`onClicked` 事件处理程序中调用了 `myFunction` 函数,并处理了它的返回值。 3. 在 C++ 中访问 QML 中的对象 如果你需要从 C++ 中访问 QML 中的对象,你可以使用 `QQuickItem` 类提供的 `findChild` 函数。例如: ```cpp QQuickItem *item = qmlEngine.rootObjects().value(0)->findChild<QQuickItem*>("myItem"); if (item) { // 处理 item 对象 } ``` 在上面的代码中,`qmlEngine.rootObjects()` 函数返回 QML 引擎中所有的根对象,`value(0)` 返回第一个根对象,`findChild` 函数用于查找名为 `"myItem"` 的子对象。 以上就是 QMLC++ 交互的基本步骤。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值