1. 程式人生 > >QML和C++程式碼之間互相呼叫及引數之間的轉換

QML和C++程式碼之間互相呼叫及引數之間的轉換

我們知道, 在QML中我們可以很容易地呼叫C++程式碼. 同樣, 我們可以在C++中呼叫放在QML中的Javascript程式碼. 由於存在函式/方法之間的呼叫, 資料型別之間的轉換是比不可少的.在今天的文章中,我們來簡單地介紹一下如何互相呼叫及一些型別的轉換.

如何從C++中呼叫QML中的Javascript程式碼

main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQuickView>

#include <QDate>
#include <QMetaObject>
#include <QVariant>
#include <QArgument>
#include <QQuickItem>
#include <QQmlContext>

#include "cmyclass.h"

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);

    QQuickView view;
    view.setSource(QUrl(QStringLiteral("qrc:///Main.qml")));
    view.setResizeMode(QQuickView::SizeRootObjectToView);

    QVariantList list;
    list << 10 << QColor(Qt::green) << "bottles";

    QVariantMap map;
    map.insert("language", "QML");
    map.insert("released", QDate(2010, 9, 21));

    QMetaObject::invokeMethod(view.rootObject(), "readValues",
            Q_ARG(QVariant, QVariant::fromValue(list)),
            Q_ARG(QVariant, QVariant::fromValue(map)));

    MyClass myclass;
    view.rootContext()->setContextProperty("myclass", &myclass);
    view.show();
    return app.exec();
}
在上面的程式碼中,我們可以看到.我們通過如下的方法:
    QMetaObject::invokeMethod(view.rootObject(), "readValues",
            Q_ARG(QVariant, QVariant::fromValue(list)),
            Q_ARG(QVariant, QVariant::fromValue(map)));

呼叫一個在Main.qml中定義的一個叫做readValues()的Javascript方法:
import QtQuick 2.0
import Ubuntu.Components 1.1

/*!
    \brief MainView with a Label and Button elements.
*/

MainView {
    // objectName for functional testing purposes (autopilot-qt5)
    objectName: "mainView"

    // Note! applicationName needs to match the "name" field of the click manifest
    applicationName: "dataconversion.liu-xiao-guo"

    /*
     This property enables the application to change orientation
     when the device is rotated. The default is false.
    */
    //automaticOrientation: true

    // Removes the old toolbar and enables new features of the new header.
    useDeprecatedToolbar: false

    width: units.gu(60)
    height: units.gu(85)

    function readValues(anArray, anObject) {
        for (var i = 0; i < anArray.length; i++ )
            console.log("Array item:", anArray[ i ])

        for (var prop in anObject) {
            console.log("Object item:", prop, "=", anObject[prop])
        }
    }

    Page {
        title: i18n.tr("dataconversion")

        Button {
            anchors.centerIn: parent

            text: "Call C++ to pass array and object"

            onClicked: {
                var i = {
                    "from" :  "
[email protected]
", "to" : "[email protected]", "message" : "This is teriffic!" }; var j = ["Saab", "Volvo", "BMW"]; myclass.callingFromQml(j, i); } } } }
上面的輸出結果為:
qml: Array item: 10
qml: Array item: #00ff00
qml: Array item: bottles
qml: Object item: language = QML
qml: Object item: released = 週二 9月 21 00:00:00 2010 GMT+0800


我們可以看出來QVariantList被對映到Javascript的Array,而QVariantMap被對映到我們Javacript中的Object.這個概念是非常重要的.我們可以在"QML Basic Types"中找到更多的關於型別之間的對映. 同樣,我們可以在Javascript中呼叫一個定義在C++程式碼中的方法,並把我們所需要的引數傳人,進而得到解析.
        Button {
            anchors.centerIn: parent

            text: "Call C++ to pass array and object"

            onClicked: {
                var i = {
                    "from" :  "[email protected]",
                    "to" :  "[email protected]",
                    "message" : "This is teriffic!"
                };

                var j = ["Saab", "Volvo", "BMW"];

                myclass.callingFromQml(j, i);
            }
        }

這裡myclass是定義在C++中的一個類的例項.我們呼叫callingFromQml()方法:
void MyClass::callingFromQml(QVariantList list, QVariantMap map) {
    qDebug() << "It is called from QML!";

    int count = list.count();
    qDebug() << "count: " << list.count();
    qDebug() << "The array values are: ";

    for ( int i = 0; i < count; i++ ) {
        QString value = list[i].toString();
        qDebug() << "value: " << value;
    }

    qDebug() << "The object values are: ";

    qDebug() << "map.from" << map["from"].toString();
    qDebug() << "map.to" << map["to"].toString();
    qDebug() << "map.message" << map["message"].toString();
}

這裡cmyclass.h定義如下:

cmyclass.h

#ifndef CMYCLASS_H
#define CMYCLASS_H

#include <QObject>
#include <QVariantList>
#include <QVariantMap>

class MyClass : public QObject
{
    Q_OBJECT
public:
    explicit MyClass(QObject *parent = 0);
    Q_INVOKABLE void callingFromQml(QVariantList list, QVariantMap map);

signals:

public slots:

};

#endif // CMYCLASS_H

注意這裡的Q_INVOKABLE,表明它是可以在QML中可以呼叫的.更多關於QML呼叫呼叫C++的介紹,請參閱文章"Exposing Attributes of C++ Types to QML".一般來說,QML可以呼叫C++ QObject類的如下成員:
  • Properties
  • Methods (providing they are public slots or flagged with Q_INVOKABLE)
  • Signals

它的輸出為:
It is called from QML!
count:  3
The array values are: 
value:  "Saab"
value:  "Volvo"
value:  "BMW"
The object values are: 
map.from "[email protected]"
map.to "[email protected]"
map.message "This is teriffic!"

整個應用的介面為:

相關推薦

QMLC++程式碼之間互相呼叫引數之間轉換

我們知道, 在QML中我們可以很容易地呼叫C++程式碼. 同樣, 我們可以在C++中呼叫放在QML中的Javascript程式碼. 由於存在函式/方法之間的呼叫, 資料型別之間的轉換是比不可少的.在今天的文章中,我們來簡單地介紹一下如何互相呼叫及一些型別的轉換. 如何

vue 父子之間函式呼叫引數接收

1.子元件呼叫父元件函式 在父元件裡面進行定於函式 export default { provide(){ return { reload:this.reload,

22.WebBrowser中JSC++程式碼互相呼叫

利用WebBrowser控制元件我們可以利用各種Web介面庫做出高大上的介面和炫酷的動畫,擴充套件性也好,甚至可以實現介面實時升級。但是有一點問題,在WebBrowser內嵌的網頁中如何訪問本地計算機硬體呢?實時上,WebBrowser內嵌的網頁中JS與本地C++程式碼可以

NCC(Normalized Cross Correlation)歸一化互相關原理C++程式碼實現

NCC(Normalized Cross Correlation)歸一化互相關 影象匹配指在已知目標基準圖的子圖集合中,尋找與實時影象最相似的子圖,以達到目標識別與定位目的的影象技術。主要方法有:基於影象灰度相關方法、基於影象特徵方法、基於神經網路相關的人工智慧

JNI學習(一)(cjava層物件互相呼叫)

c層呼叫java物件 package com.example.bean; /** * * java物件 * @author telenewbie * */ public class JNI_cCalljava_test { publi

《Linux作業系統分析》之使用庫函式APIC程式碼中嵌入彙編程式碼兩種方式使用同一個系統呼叫

本篇文章分析的是使用庫函式API和C程式碼中嵌入彙編程式碼兩種方式使用同一個系統呼叫,來說明在Linux系統中,系統呼叫的實現機制。 相關知識 首先關於這篇文章會介紹一些用到的知識。 一、什麼是核心態,什麼又是使用者態。 核心態:在高執行級別下,程式碼可以執行特權指令,

DelphiC++builder中的MessageBox相近的四種訊息框

       Delphi中平常使用的訊息框有四種形式,有ShowMessage、MessageDlg、Application.MessageBox、MessageBox。下面來深入瞭解下這四種形式的實現和使用。1.ShowMess

使用AndroidStudio打包OpenCVC++程式碼並在安卓上執行

使用AndroidStudio打包OpenCV和C++程式碼並在安卓上執行 在為伺服器部署OpenCV和C++的過程中嘗試了很多方法,這裡記錄一下在AndroidStudio上打包OpenCV和C++的過程。 1.準備開發環境 這裡我直接在mac上開發,沒有在虛擬機器中。 安

unity3d 中JavaScript指令碼C#指令碼的相互呼叫

本人親測unityd5.56版本,開啟Unity在Project檢視下新建資料夾Standard Assets。新建JavaScript指令碼:testJs,C#指令碼testCs. testJs程式碼如下: function OnGUI()     {       

CC++程式碼精粹》讀書筆記

最近看了<<C和C++程式碼精粹>>, 涉及到C++的指標,異常處理等方方面面,其中有些自認為非常不錯的程式碼,在工作中非常值得借鑑。 1.指向成員函式的指標 A #include<iostream> using namespace std

IntelliJ IDEA平臺下JNI程式設計(五)—本地C程式碼建立Java物件引用

本文學習如何在C程式碼中建立Java物件和物件陣列,前面我們學習了C程式碼中訪問Java物件的屬性和方法,其實在建立物件時本質上也就是呼叫建構函式,因此本文知識學習起來也很輕鬆。有了前面學習陣列建立的方法後,C程式碼建立物件陣列同樣很容易,下面開始學習吧~

詳解Huffman壓縮原理c++程式碼實現

寫在前面    Huffman壓縮原理其實挺好理解的,我用java很快就寫好了。然後用c++寫,一開始我是這麼想的:c++偏底層,應該對二進位制串檔案的讀寫會更簡單吧。    不涉及到檔案讀寫的部分確實很快就做好了,然後就被檔案讀寫折磨。    各種深夜痛哭... ... 

Mvn模組之間互相呼叫

模組之間互相呼叫 今天因為版本問題,需要在moudle_A(hive版本1.x,其實就是一個空殼,僅僅因為資料庫數hive.1.x)中呼叫moudle_b中的內容,因為hive.2.x中的新功能,無法

.NET中WebBrowser控制元件內部頁面的JS程式碼與外部C#程式碼的相互呼叫

場景1:C#程式呼叫JS函式重新整理網頁,輸出再見兩字;測試目標:C#呼叫JS函式 場景2:C#程式呼叫JS函式重新整理網頁,輸出文字為使用者輸入的文字;測試目標:C#呼叫帶引數的JS函式 場景3:C#程式呼叫JS函式獲取今日的年月日資訊(yyyy-MM

編譯原理(九) LR(0)文法分析法(演算法描述C++程式碼實現)

後期DEBUG發現make_set函式和make_go存在問題,於2015年12月4日更新了程式碼,見諒 概念梳理 最左推導:每一步替換最左邊的非終結符 最右推導:每一步替換最右邊的非終結符,最右推導稱為規範推導 短語:令G是一個文法,S是文法的開始符號

LLVM與C++程式碼的相互呼叫(全註釋)

一、在C++中呼叫LLVM編寫的IR函式 #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" #include "llvm/IR/Function.h" #include "llvm/IR/BasicBlock.h" #i

關於AT&T彙編c語言的相互呼叫的分析

這方面很多人寫了blog,這次我也是學習,從objdump等工具分析。 ------------------------c中調用匯編------------------------------- 首先給出c檔案 #include<stdio.h> int m

[Android Studio] 向您的專案新增 C C++ 程式碼

搭配使用 Android Studio 2.2 或更高版本與 Android Plugin for Gradle 版本 2.2.0 或更高版本時,您可以將 C 和 C++ 程式碼編譯到 Gradle 與 APK 一起打包的原生庫中,將這類程式碼新增到您的應用中。您的 J

Swift中不用橋接檔案.h標頭檔案直接C程式碼互動的方法

我們知道一般情況下Swit要想呼叫obj-c,c或c++程式碼必須通過obj-c以及橋接檔案才可以辦到,但是對於某些簡單的程式碼,我們可以跳過橋接檔案和.h標頭檔案,直接和C程式碼互動呢! 我們再Project中新增一個.c檔案,不要建立橋接檔案和對應的.h標

關於C#與Delphi DLL呼叫回撥問題注意事項

1.Delphi封裝的函式API及定義的函式型別(用於回撥)中引數的修飾關鍵詞盡不使用const 2.Delphi封裝的函式API及定義的函式型別(用於回撥)中引數的修飾關鍵詞使用const,對應C#中申明需帶ref 3.Delphi封裝的函式API及定義的函式型別(用於回