前言
在Qml和QWidget混合开发中,少不了C++与qml的互相调用,之前总结了一下在qml中调用c++的方法,那反过来如何在业务逻辑中直接修改qml呢?
qml调用c++总结
C++调用QML
C++调用Qml,主要可以分为两种
- 修改属性
- 调用qml中的函数
那如何让C++知道具体要修改or调用的Qml是什么呢?
把要修改的qml控件,增加“objectName”属性,这样,就可以在Qt的元对象系统中进行查找
import QtQuick 2.12
import QtQuick.Window 2.14
import QtQuick.Controls 2.14
import QtQuick.Controls.Styles 1.4
Rectangle {
color: "gray"
radius:10
Image {
id:background_image
anchors.fill: parent
fillMode: Image.PreserveAspectCrop
source: "http://cube.elemecdn.com/6/94/4d3ea53c084bad6931a56d5158a48jpeg.jpeg"
antialiasing: true
objectName: "image_test_obj"//能在Qt元对象中查找的关键
function updateSource(text) {
source=text;
console.log("updateSource=" + source);
}
property int enable_see: 5
}
}
查找的方式
//如果是通过QQuickWidget加载的
auto cpp_qml_widget_ = new QQuickWidget();
cpp_qml_widget_->setResizeMode(QQuickWidget::SizeRootObjectToView);
cpp_qml_widget_->setSource(QUrl("cpp_to_qml.qml"));
cpp_qml_widget_->show();
ui.verticalLayout->addWidget(cpp_qml_widget_);
auto obj_image =cpp_qml_widget_->rootObject()->findChild<QObject *>("image_test_obj");
//
假设我们要修改一个这个image的背景,我们就通过两种方式分别实现该功能
直接访问Qml控件属性
通过setProperty进行更改item原有的属性及自定义的property
{
auto obj_image = cpp_qml_widget_->rootObject()->findChild<QObject *>("image_test_obj");
obj_image->setProperty(
"source",
"http://image.nbd.com.cn/uploads/articles/images/673466/500352700_banner.jpg");
auto enable_see= obj_image->property("enable_see").toInt();//5
}
访问Qml中的函数
访问函数是通过QMetaObject::invokeMethod
这里有个注意点,在qml中不支持函数名首字母大写,务必小写
{
auto obj_image =
cpp_qml_widget_->rootObject()->findChild<QObject *>("image_test_obj");
QMetaObject::invokeMethod(
obj_image, "updateSource",
Q_ARG(QVariant,
"http://image.nbd.com.cn/uploads/articles/images/673466/500352700_banner.jpg"));
}
其次在QMetaObject::invokeMethod调用qml函数中,基础类型要用QVariant