mix QML and C++

文章属于原创,转载请注明出处,有一部份内容保持英文,方便理解  大笑 

      我们知道 ,通过Qt Declarative module ,C++可以动态创建和操纵QML的组件(cpmponents) ,

我们利用这些API使用C++来拓展我们的QML程序,反过来也可以将QML嵌入到你的C++程序中。

通过Qt的元对象系统( Qt‘s metaobject system),我们可以利用Qt中的信号与槽机制使QML 和 Qt

objects 相互通信(communicate)。另外,QML plugins可以用来创建可复用的QML 组件。 

使用C++和QML混合编程可能出于以下原因:You may want to mix QML and C++ for a number of reasons. For example:

  • To use functionality defined in a C++ source (for example, when using a C++ Qt-based data model,
  • or calling functions in a third-party C++ library)
  • To access functionality in the Qt Declarative module (for example, to dynamically generate images usingQDeclarativeImageProvider)
  • To write your own QML elements (whether for your applications, or for distribution to others

首先我们介绍下Qt Declarative module 中几个核心的类

QDeclarativeEngine: QML的执行环境,负责解释执行QML代码。每一个程序都应至少包含一个engine 实例 ;

QDeclarativeComponent:创建一个封装了QML文件的组件;

QDeclaraContext:提供了一个允许C++程序将数据暴露给由QDeclaraEngine 创建的 QML 组件的上下文环境;

例如:

 QDeclarativeEngine engine;
 QDeclarativeComponent component(&engine, QUrl::fromLocalFile("MyRectangle.qml"));
 QObject *rectangleInstance = component.create();

 // ...
 delete rectangleInstance;
 //QObject * QDeclarativeComponent::create (QDeclarativeContext * context = 0 ) [virtual]

QML我们如何与C++一起使用

我们如何通过C++拓展我们的QML呢?

1.我们可以通过C++动态创建一个QML组件并且我们能够对它进行一些操作

2.我们可以使一个C++对象(比如:继承自QObject的类的对象)和他的属性作为一个QML的组件

3.定义一个QML组件


Loading QML Components from C++

QDeclarativeComponent 将一个QML组件(文件)装载成一个C++  Object(对象)。使用QDeclarativeComponent需要调用QDeclarativeComponent::create()来创建一个组件的实例 ;QDeclarativeView同样也可以装载一个QML组件(文件),但是QDeclarativeView也继承自QGraphicsView ,所以他可以将QML组件或文件显示出来。另外他将自动的创建一个QML Component的实例 (可以通过QDeclarativeView::rootObject()获得)两者用法区别很明显。

 import QtQuick 1.0

 Item {
     width: 100; height: 100
 }

 // Using QDeclarativeComponent
 QDeclarativeEngine engine;
 QDeclarativeComponent component(&engine,
         QUrl::fromLocalFile("MyItem.qml"));
 QObject *object = component.create();
 ...
 delete object;
 // Using QDeclarativeView
 QDeclarativeView view;
 view.setSource(QUrl::fromLocalFile("MyItem.qml"));
 view.show();
 QObject *object = view.rootObject();
object是MyItem.qml的C++实例。我们可以通过 QObject::setProperty() or QDeclarativeProperty: 设置Item的属性

,比如:

 object->setProperty("width", 500);
 QDeclarativeProperty(object, "width").write(500);
另外,我们将object进行类型转换,转换为其原来的类型,比如:
 QDeclarativeItem *item = qobject_cast<QDeclarativeItem*>(object);
 item->setWidth(500);

通过MetaObject::invokeMethod() 和QObject::connect(),我们可以连接、调用定义在component的函数。


下面我们来说如何获得子对象(上面我们得到是其根对象Item)

QObject::objectNameproperty with QObject::findChild()

例如:

 import QtQuick 1.0

 Item {
     width: 100; height: 100

     Rectangle {
         anchors.fill: parent
         objectName: "rect"
     }
 }
上面的例子中裉对象Item有一个子对象Rectangle,我们该如何得到他呢?

 QObject *rect = object->findChild<QObject*>("rect");
 if (rect)
     rect->setProperty("color", "red");
还有一种情况需要考虑,在delegate(ListView,Repeater)或其他需要创建很多实例时会获得很多具有相同名字的子对象,我们用 QObject::findChildren()可以得到所有具有相同名字的子对象。不推荐这么做。


进入的下篇:

Embedding C++ objects into QML components

上面介绍了如何将QML中组件在C++中实例化,之后修改其属性。这一部分我们将介绍如何将C++ 对象嵌入到QML组件中。当我们将QML 载入到C++ 程序中时,能够直接将C++ data 数据传入QML object 是非常有用的。 我们通过QDeclarativeContext,可以将C++数据暴露给QML 组件 的上下文环境中 ,可以让C++ 数据注入到QML中。

例如:我们有一个QML item 需要引用一个currentDateTime 值(这需要Qt 来提供,在QML中无法获取系统时间),

 // MyItem.qml
 import QtQuick 1.0

 Text { text: currentDateTime }
此时我们可以用C++直接设置这个值。首先我们需要通过载入QML 组件(文件)
QDeclarativeView view;
view.rootContext() //获得C++ object 
 然后通过QDeclarativeContext::setContextProperty():设置currentDateTime

完整的:

 QDeclarativeView view;
 view.rootContext()->setContextProperty("currentDateTime", QDateTime::currentDateTime());
 view.setSource(QUrl::fromLocalFile("MyItem.qml"));
 view.show();

上下问属性值可以是QVariant (如上例),也可以是QObject* ,这些对象可以在QML中被读取修改。例如:


 class ApplicationData : public QObject
 {
     Q_OBJECT
 public:
     Q_INVOKABLE QDateTime getCurrentDateTime() const {
         return QDateTime::currentDat
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值