今天写程序的时候想在widget中添加一个qml的控件,一番周折最后使用QuickWidget进行实现,这儿做一下简单记录,一是防止自己忘记,同时还帮助可能需要类似功能的朋友
过程简介
1. 在widget中从右侧拖入一个QuickWidget,这个简单方便
2. 设置QuickWidget的source,这个在ui中就可以实现,依然简单方便
下面重点讲解下双方的数据交互
1. 使用信号槽的方式连接
参数是可以自由传递的,目前测试了QVariant和int,所以应该都可以传输,不过以前测试过,qml中不支持结构体,这次懒惰没有测试
小细节:
a . 注意在qml中var,在c++中是QVariant
b. 注意c++中写connect的时候qml的信号不提示,这块需要自己抄过来,这个让我困了一会
connect(this, SIGNAL(signalFromWidget(QVariant)), ui->quickWidget->rootObject(), SLOT(slotInQML(QVariant)));
connect(ui->quickWidget->rootObject(), SIGNAL(mySignalFromQml(QVariant, int)), this, SLOT(slotPrint(QVariant, int)));
在c++中设置信号和槽比较简单,QML中信号和槽的格式如下
signal mySignalFromQml(var s, int i);// QML中的信号
function slotInQML(str) // QML中的槽
{
console.log(str)
}
2. 使用上下文的方式,在qml中访问c++的数据
这个相当方便,只需要一句话
ui->quickWidget->rootContext()->setContextProperty("Test", this);
然后在qml中就可以访问了
Button
{
id: button
text: "hello world"
onClicked: {
console.log("button clicked")
background: Test.sendData();
console.log(Test.sendData())
Test.setData("str from qml")
mySignalFromQml("signal from qml",55);
}
}
3. 使用property的方式,在c++中访问qml的变量
也很简单,只需要一句话
qDebug() << ui->quickWidget->rootObject()->property("sData").toInt();
其中sData是qml中的变量,定义方式为
property var sData: 50
4. 其实还有几种方式,比如使用这种方式,是大神写的,由于我已经满足了自己的需求,可以实现双方的信号槽以及变量的访问,所以就不在研究了,大家可以看一下,具体我没有测试
QQuickWidget *view = new QQuickWidget;
view->setSource(QUrl("qrc:/View.qml"));
QVariant retVal;
QMetaObject::invokeMethod(view->rootObject(), /* Qml实例 */
"execute", /* 函数名字 */
Qt::DirectConnection, /* 连接方式 */
Q_RETURN_ARG(QVariant, retVal), /* 标记返回值 */
Q_ARG(QVariant, "Hello"), /* 输入参数1 */
Q_ARG(QVariant, "world"));/* 输入参数2 */
qDebug() << "value: " << retVal;
view->show();