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 协议规定转载,请在正文中标注并保留本人信息。
  • 相关阅读:
    JavaScript数组升降序排列、最大值、最小值等
    css3箭头
    隐藏显示
    最后一个 last-of-type
    jquery函数封装
    为什么要使用rem
    Git的使用--如何将本地项目上传到Github
    jQuery判断是否选中
    数组索引赋值
    HTML中input和button设置同样高度却不能等高的原因
  • 原文地址:https://www.cnblogs.com/brifuture/p/6514112.html
Copyright © 2011-2022 走看看