文档章节

QML与Qt C++ 交互机制探讨与总结

首席吹牛官
 首席吹牛官
发布于 2015/05/22 12:58
字数 1053
阅读 43
收藏 2

介绍

QML和 C++对象可以通过,signals,slots和 属性修改进行交互。对于一个C++对象,任何数据都可以通过Qt的 Meta-Object System暴露给QML(何总方法,后面介绍),同时,任何的QML对象数据通过Meta-object system在C++端直接访问。
在实际的项目中很多地方会用到QML与Qt C++交互。在这里总结了若干方法供大家参考,欢迎大家指导和拍砖。

在这里不外乎有三种方法:
1. 把Qt C++中的对象或类型暴露给 QML端,供QML端使用。(官方说法是“嵌入”而非“暴露”,比较文明。- -b)
2. QML中的Signal Handler(相当于Qt C++发送信号给QML端,QML端的Signal Handler进行处理)。
3. 在Qt C++端创建QML对象,既然对象都有了。那你想怎么样它就怎么样它呗。(没用过,看起来也不太实用,不过介绍介绍,有用过的同学留言哈)。

好,我们开始吧~

知识准备

别急,让我们先来看看,一些东西,如果您都知道,可以跳过此节。
QML API有三个主要成员——QDeclarativeEngineQDeclarativeComponentQDeclarativeContext

QDeclarativeEngine提供了QML的运行环境。
QDeclarativeComponent封装了QML Documents
QDeclarativeContext允许程序使用QML组件显示数据。

QML包含一个非常好用的API——QDeclarativeView。通过它,应用程序可以很方便的把QML组件嵌入到QGraphicsView中。QDeclarativeView主要用于在应用程序开发过程中进行快速原型开发。

暴露Qt C++的对象或类型给QML

创建需要暴露给QML的数据类型

#ifndef MYCLASS_H
#define MYCLASS_H
#include <QObject>
#include <QString>
class MyClass : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QString myString READ myString WRITE setmyString NOTIFY myStringChanged)
public:
    explicit MyClass(QObject *parent = 0);
    Q_INVOKABLE QString getMyString();
signals:
    void myStringChanged();
public slots:
    void setmyString(QString aString);
    QString myString();
private:
    QString m_string;
};
#endif // MYCLASS_H

若你想数据元素中的方法可以被QML直接调用有2种方法:
1. 在函数申明前添加 Q_INVOKABLE 宏。
2. 申明成public slots。

QML可以直接访问改数据元素的属性,该属性由QPROPERTY所申明。
具体实现请参考,示例代码。

暴露已存在的Qt C++对象给QML

//main.cpp
MyClass myObj;
QDeclarativeEngine *engine=viewer.engine();
QDeclarativeContext *context=engine->rootContext();
context->setContextProperty("myObjectExposeByCXProperty", &myObj);

qml中可以直接使用myObjectExposeByCxProperty对象。

//mainpage.qml
...
Button{
    ...
    id:btn1
    ...
    text: qsTr("PROPERTY") 
    //此处调用myString为MyClass的QPROPERTY的属性不是方法,所以没有括号。
    onClicked: label.text=myObjectExposeByCXProperty.myString;
}
...

注册Qt C++类类型给QML

另外一种方式是注册类型

//main.cpp
qmlRegisterType<MyClass>("RegisterMyType", 1, 0, "MyClassType");

QML中这样使用

//mainpage.qml
...
import RegisterMyType 1.0
Button{
    id:btn2
    ...
    text: qsTr("INOVKABLE")
    //此处调用的时INVOKABLE的方法,不是属性,所以有括号。
    onClicked: label.text=myclassExposeByRegType.getMyString();
}
//创建对象,由于QML是解释执行的,所以放后面也没什么关系。
MyClassType
{
    id:myclassExposeByRegType
}

步骤:
1. 导入import。
2. 创建对象。
3. id直接使用。

QML中的Signal Handler

还是使用上面的那例子,在qml中点击按钮控件,改变其中对象的字符串,这时候在Qt C++中发送一个signal信号给qml端,qml端接收到使用signal handler响应,改变label2的值。具体代码如下。
qml中修改string的值。

//mainpage.qml
Button{
    id:btn3
    text: qsTr("emit stringchanged signal")
    onClicked: myObjectExposeByCXProperty.myString="xxxxx";    
}

Qt C++触发信号

//myclass.cpp
void MyClass::setmyString(QString aString)
{
    if(aString==m_string)
    {
        return;
    }
    m_string=aString;
    emit myStringChanged();
}

连接signal handler响应

//mainpage.qml
Connections
{
    target: myObjectExposeByCXProperty
    onMyStringChanged:label2.text="Signal handler received"   
}

Qt C++中直接调用QML的函数

同样的QML的函数也可以被Qt C++端调用。
所有的QML函数都通过meta-object system暴露Qt C++端,在Qt C++端可以使用QMetaObject::invokeMethod()方法直接调用。下面就是这样的一个例子。

// MyItem.qml
 import QtQuick 1.0
 Item {
  function myQmlFunction(msg) {
  console.log("Got message:", msg)
  return "some return value"
  }
 }
// main.cpp
 QDeclarativeEngine engine;
 QDeclarativeComponent component(&engine, "MyItem.qml");
 QObject *object = component.create();
 QVariant returnedValue;
 QVariant msg = "Hello from C++";
 QMetaObject::invokeMethod(object, "myQmlFunction",
  Q_RETURN_ARG(QVariant, returnedValue),
  Q_ARG(QVariant, msg));
 qDebug() << "QML function returned:" << returnedValue.toString();
 delete object;

注意:QMetaObject::invokeMethod()方法中的参数Q_RETURN_ARG()和Q_ARG()都被定义为QVariant类型,此类型是QML函数的的参数和返回值的通用数据类型。


转自:http://www.developer.nokia.com/Community/Wiki/QML%E4%B8%8EQt_C%2B%2B_%E4%BA%A4%E4%BA%92%E6%9C%BA%E5%88%B6%E6%8E%A2%E8%AE%A8%E4%B8%8E%E6%80%BB%E7%BB%93

© 著作权归作者所有

上一篇: Qt mvc 三
下一篇: 二维码生成
首席吹牛官
粉丝 9
博文 368
码字总数 191938
作品 0
闵行
程序员
私信 提问
QML入门教程之 Hello world

QML是什么? QML是一种描述性的脚本语言,文件格式以.qml结尾。语法格式非常像CSS(参考后文具体例子),但又支持javacript形式的编程控制。 它结合了QtDesigner UI和QtScript的优点。QtDesig...

红薯
2011/06/02
968
0
Qt设计模式(第二版):谁最需要本书?

情人节前夕,突然受邀作为本书中文版的审校,心中在惊喜之余,也有些诚惶诚恐。能与闫老师(yfx2003)合作,共同学习与探讨,确是一件幸事;但是自己真的能胜任该工作么?一开始心里还真是没底...

晨曦之光
2012/05/08
2.7K
0
如何使用 Qt 开发音视频通话应用

作者:单辉,声网 Agora 高级开发工程师。 众所周知,Qt 是一个跨平台的 C++ 图形用户界面应用程序开发框架,它具有跨平台、丰富的 API、支持 2D/3D 图形渲染、支持 OpenGL、开源等优秀的特性...

声网Agora
05/29
0
0
【北京】某互联网服务公司招聘linuxC++(QT)方向工程师

1、高级QT工程师(C++)(北京) 要求: 1、扎实的C++基础 2、良好的编程风格,较强的英语阅读能力 3、精通Qt布局、绘图、网络技术 4、熟悉QML OpenGL 多媒体技术 5、至少两年Qt跨平台开发经验...

sabrinazhu
2012/04/24
1K
13
Qt不会安装?C/C++学习之详细Qt安装教程,傻瓜式安装模式启动

Qt 安装 1.1 QT下载地址 http://download.qt.io/archive/qt/ 1.1.1 选择下载版本 1.1.2 下载结束,双击exe运行安装 1.2 认识Qt Creator 1.2.1 QtCreator 窗口 1.2.2 Qt项目 1.2.2.1 Qt 空项目...

这个人很懒什么都没留下
07/16
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Spring Boot + Mybatis-Plus 集成与使用(二)

前言: 本章节介绍MyBatis-Puls的CRUD使用。在开始之前,先简单讲解下上章节关于Spring Boot是如何自动配置MyBatis-Plus。 一、自动配置 当Spring Boot应用从主方法main()启动后,首先加载S...

伴学编程
昨天
7
0
用最通俗的方法讲spring [一] ──── AOP

@[TOC](用最通俗的方法讲spring [一] ──── AOP) 写这个系列的目的(可以跳过不看) 自己写这个系列的目的,是因为自己是个比较笨的人,我曾一度怀疑自己的智商不适合干编程这个行业.因为在我...

小贼贼子
昨天
7
0
Flutter系列之在 macOS 上安装和配置 Flutter 开发环境

本文为Flutter开发环境在macOS下安装全过程: 一、系统配置要求 想要安装并运行 Flutter,你的开发环境需要最低满足以下要求: 操作系统:macOS(64位) 磁盘空间:700 MB(不包含 IDE 或其余...

過愙
昨天
6
0
OSChina 周六乱弹 —— 早上儿子问我他是怎么来的

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @凉小生 :#今日歌曲推荐# 少点戾气,愿你和这个世界温柔以待。中岛美嘉的单曲《僕が死のうと思ったのは (曾经我也想过一了百了)》 《僕が死の...

小小编辑
昨天
2.7K
16
Excption与Error包结构,OOM 你遇到过哪些情况,SOF 你遇到过哪些情况

Throwable 是 Java 中所有错误与异常的超类,Throwable 包含两个子类,Error 与 Exception 。用于指示发生了异常情况。 Java 抛出的 Throwable 可以分成三种类型。 被检查异常(checked Exc...

Garphy
昨天
42
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部