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!"
整個應用的介面為:
相關推薦
QML和C++程式碼之間互相呼叫及引數之間的轉換
我們知道, 在QML中我們可以很容易地呼叫C++程式碼. 同樣, 我們可以在C++中呼叫放在QML中的Javascript程式碼. 由於存在函式/方法之間的呼叫, 資料型別之間的轉換是比不可少的.在今天的文章中,我們來簡單地介紹一下如何互相呼叫及一些型別的轉換. 如何
vue 父子之間函式呼叫及引數接收
1.子元件呼叫父元件函式 在父元件裡面進行定於函式 export default { provide(){ return { reload:this.reload,
22.WebBrowser中JS和C++程式碼互相呼叫
利用WebBrowser控制元件我們可以利用各種Web介面庫做出高大上的介面和炫酷的動畫,擴充套件性也好,甚至可以實現介面實時升級。但是有一點問題,在WebBrowser內嵌的網頁中如何訪問本地計算機硬體呢?實時上,WebBrowser內嵌的網頁中JS與本地C++程式碼可以
NCC(Normalized Cross Correlation)歸一化互相關原理和C++程式碼實現
NCC(Normalized Cross Correlation)歸一化互相關 影象匹配指在已知目標基準圖的子圖集合中,尋找與實時影象最相似的子圖,以達到目標識別與定位目的的影象技術。主要方法有:基於影象灰度相關方法、基於影象特徵方法、基於神經網路相關的人工智慧
JNI學習(一)(c和java層物件互相呼叫)
c層呼叫java物件 package com.example.bean; /** * * java物件 * @author telenewbie * */ public class JNI_cCalljava_test { publi
《Linux作業系統分析》之使用庫函式API和C程式碼中嵌入彙編程式碼兩種方式使用同一個系統呼叫
本篇文章分析的是使用庫函式API和C程式碼中嵌入彙編程式碼兩種方式使用同一個系統呼叫,來說明在Linux系統中,系統呼叫的實現機制。 相關知識 首先關於這篇文章會介紹一些用到的知識。 一、什麼是核心態,什麼又是使用者態。 核心態:在高執行級別下,程式碼可以執行特權指令,
Delphi和C++builder中的MessageBox及相近的四種訊息框
Delphi中平常使用的訊息框有四種形式,有ShowMessage、MessageDlg、Application.MessageBox、MessageBox。下面來深入瞭解下這四種形式的實現和使用。1.ShowMess
使用AndroidStudio打包OpenCV和C++程式碼並在安卓上執行
使用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() {
《C和C++程式碼精粹》讀書筆記
最近看了<<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及定義的函式型別(用於回