zoukankan      html  css  js  c++  java
  • QtQuick 中的 qml 与 Qt 的 C++

    QtQuick 可以使用内置的 JavaScript 引擎加载相应的 JS 代码,使用起来特别方便。

    在 Qt 中使用 C++ 开发底层,QtQuick 用来加载、处理图像,然后使用 Qt 提供的接口保证两者能够正常通信即可。

    1. 首先用Qt Creator新建项目,选择Qt Quick Controls 2 Application,命名项目…

    2. 在资源文件qml.qrc中添加一个qml文件,命名…

    3. 在qml文件中输入相应的元素(Item,Rectanger,Image,Canvas等等)。

    1 import QtQuick 2.0
    2 import QtQuick.Window 2.2
    3 
    4 Window {
    5      800
    6     height: 600
    7     visible: true
    8     title: "Test window"
    9 }

    这里仅用了一个 Window 元素,加载后只显示一个空白的窗体。

    4. 在main函数中加载qml引擎需要用到QQmlApplicationEngine类,通过该类加载qml文件。如下:

     1 int main(int argc, char *argv[])
     2 {
     3     QGuiApplication app(argc, argv);
     4 
     5     QQmlApplicationEngine engine;
     6     engine.load(QUrl(QStringLiteral("qrc:/Test.qml"))); 7 
     8     return app.exec();
     9 }

    其中,engine 对象的 load() 方法,需要一个QUrl对象提供qml文件的url路径,这里加载了一个qml文件,即“Test.qml”文件。

    运行之后得到空白的窗体。如果想要显示不同的内容,需要在qml文件中添加相应的元素或自己编写控件再添加。

    用 QQmlApplicationEngine 加载的 qml 文件可以使用 QML 的 Window 控件。

    但是在c++ 的类方法中无法直接使用 QQmlApplicationEngine 类,若使用该类加载 qml 文件,会导致在触发显示窗口事件时,窗口显示一下立即消失,但是程序依然在运行,因此就无法对qml窗口进行操作。

    1 void Data::view() {
    2         QQmlApplicationEngine engine;
    3         engine.load(QUrl(QStringLiteral("qrc:/Test.qml")));
    4 }

    在Data类的view()方法中使用 QQmlApplicationEngine load() 方法无法正常显示窗口。

     那么,如何在方法中调用加载 qml 文件呢?

    要在 c++ 文件中显示qml文件的内容,Qt 提供了 QQuickView 类(QtQuick1.0则是使用 QDeclaritiveView 类,但是该类在加载 qml 文件时,响应缓慢)使用 QQuickView 即可加载 qml 并显示内容。

     1 void Data::view() {
     2     QQuickView *compassview = new QQuickView;
     3     compassview->setSource(QUrl(QStringLiteral("qrc:/Compass.qml")));
     4 //    compassview->rootContext()->setContextProperty("dataRadius", this);
     5     QQmlContext *context = compassview->rootContext();
     6     context->setContextProperty("dataSource", this);
     7     // 设置窗口图标
     8     QIcon icon = QIcon(QStringLiteral(":/img/compass.ico"));
     9     compassview->setIcon(icon);
    10 //    compassview->set
    11     // 设置窗口缩放时,根对象也会随之缩放
    12     compassview->setResizeMode(QQuickView::SizeRootObjectToView);
    13     compassview->setTitle("Compass heading pitch & roll");
    14     compassview->show();
    15 
    16 }

    compassview 指向一个 QQuickView 对象,setSource() 方法指定该 QQuickView 对象所要加载的qml文件。

    而 compassview->rootContext() 则是获取对象的根元素上下文,然后用 context 对象的 setContextProperty(const QString *, const QVariant*) 方法设定上下文属性,即可通过 QVariant 指针从 C++ 向 QML 传递数据。

    然而如果qml文件是以 Window 作为根元素的话,QQuickView加载时会出现一个警告,因为QQuickView继承自QQuickWindow(又继承自QWindow),它本身就是一个窗口类,如果再用 QML 的 Window 控件作为根元素,自然会出现警告,可以忽略掉该警告,也可以将 Window 改成 Item (但要注意,Window 的有些属性在 Item 中不存在),这样就不会出现警告了。 

    然后在 qml 文件中通过设定一个定时器 Timer,可以定时从 c++ 中获取数据。

     1     /*
     2      * 设置一个定时器,每隔 500ms 就从数据源中读取数据,修正图像
     3     */
     4     Timer {
     5         id: updateTimer
     6         interval: 500
     7         running: true
     8         repeat: true
     9 
    10         onTriggered: {
    11 //            console.log("Timer is triggered! ")
    12 //            var data = DataSource.getData();
    13             var data = dataSource.getRadius()
    14 
    15             data = [0, 0, 0]
    16 //            h_refresh(data[0])
    17             refresh(data[0], data[1], data[2])
    18         }
    19     }

    qml中 dataSource 需要与上面的 setContextProperty(“dataSource”, this) 语句中的 dataSource 同名(这样就可以直接调用相关对象的方法,比如 getRadius() 方法),否则 qml 将无法获取数据。

    C++ 中设置 QQuickView 的窗口图标、标题等等与 QWindow 类似。

    compassview->setResizeMode(QQuickView::SizeRootObjectToView) 设置了根对象大小随窗口大小改变而改变。这样就能动态缩放qml内容。

    --------------------------------------------------------------------------------

    另外需要注意的是,如果先用 Qt 新建了一个 Qt 应用,想要再添加 qml 文件并运行,需要修改项目的 .pro 文件,添加以下内容:

    QT += qml quick

    这样,在编译时才不会出错。

    ====================================================

    另外,附上完整的代码

    https://github.com/GitFuture/Compass

    本博客由 BriFuture 原创,并在个人博客(WordPress构建) BriFuture's Blog 上发布。欢迎访问。
    欢迎遵照 CC-BY-NC-SA 协议规定转载,请在正文中标注并保留本人信息。
  • 相关阅读:
    POJ 3259 Wormholes【BellmanFord】
    POJ 2960 SNim【SG函数的应用】
    ZOJ 3578 Matrixdp水题
    HDU 2897 邂逅明下【bash博弈】
    BellmanFord 算法及其优化【转】
    【转】几个Java的网络爬虫
    thinkphp 反字符 去标签 自动加点 去换行 截取字符串 冰糖
    php 二维数组转 json文本 (jquery datagrid 数据格式) 冰糖
    PHP 汉字转拼音(首拼音,所有拼音) 冰糖
    设为首页与加入收藏 兼容firefox 冰糖
  • 原文地址:https://www.cnblogs.com/brifuture/p/6514112.html
Copyright © 2011-2022 走看看