QML與C++幾種交互方式
QML調(diào)用CPP函數(shù)
要求:
- 使用 Q_OBJECT 宏需要繼承 QObject 類。Q_OBJECT能夠啟用信號和槽機(jī)制、使用動態(tài)屬性系統(tǒng)。(使用 Q_OBJECT 宏的類需要通過Qt的元對象編譯器(moc)進(jìn)行處理。)
- 使用 Q_INVOKABLE 修飾要暴露給 QML 的函數(shù)。
1.在main.cpp中進(jìn)行注冊
// 注冊c++類到qml 參數(shù)分別為導(dǎo)入的 模塊名稱 主版本號 次版本號 模塊名稱 qmlRegisterType<CppObject>("CppObject",1,0,"CppObject");
2.在qml中導(dǎo)入
import CppObject 1.0 CppObject{ id:cppobj }
3.通過id+方法名的方式調(diào)用
// 加上這個宏,當(dāng)前函數(shù)就可以被qml訪問調(diào)用 Q_INVOKABLE void func();
//test.h #ifndef TEST_H #define TEST_H #include <QObject> #include "QDebug" class CppObject : public QObject { Q_OBJECT public: explicit CppObject(QObject *parent = nullptr); //通過宏定義在qml使用cpp類中的函數(shù) Q_INVOKABLE void print_(QString str) { qDebug() << str; } }; #endif // TEST_H
//main.cpp #include <QGuiApplication> #include <QQmlApplicationEngine> #include <QLocale> #include <QTranslator> #include "test.h" int main(int argc, char *argv[]) { #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); #endif QGuiApplication app(argc, argv); QTranslator translator; const QStringList uiLanguages = QLocale::system().uiLanguages(); for (const QString &locale : uiLanguages) { const QString baseName = "untitled_" + QLocale(locale).name(); if (translator.load(":/i18n/" + baseName)) { app.installTranslator(&translator); break; } } //主要是這里其他的都是默認(rèn)的 // 注冊c++類到qml 參數(shù)分別為導(dǎo)入的 模塊名稱 主版本號 次版本號 模塊名稱 qmlRegisterType<CppObject>("CppObject",1,0,"CppObject"); QQmlApplicationEngine engine; const QUrl url(QStringLiteral("qrc:/main.qml")); QObject::connect( &engine, &QQmlApplicationEngine::objectCreated, &app, [url](QObject *obj, const QUrl &objUrl) { if (!obj && url == objUrl) QCoreApplication::exit(-1); }, Qt::QueuedConnection); engine.load(url); return app.exec(); }
//main.qml import QtQuick 2.15 import QtQuick.Window 2.15 import QtQuick.Controls 2.15 import CppObject 1.0 Window { id: win width: 800 height: 600 visible: true title: qsTr("Hello World") CppObject{ id:cppobj } Button{ width: 50 height: 50 background: Rectangle{ color:"red" } onClicked: { //obj.printMsg() cppobj.print_("test") } } }
定義全局變量,注冊到上下文
樣例:
#include <QQmlContext> QQmlApplicationEngine engine; //這兩句是重點,設(shè)置全局變量 QQmlContext *context = engine.rootContext(); context->setContextProperty("SCREEN_WIDTH", 800);
也可以用此方法將類對象暴露給QMLsetContextProperty兩個參數(shù)表示的意義為:
- 第一個參數(shù)表示 qml 可以識別的對象名
- 第二個參數(shù)表示 C++ 對象
#include <QtQml/QQmlContext> #include "vacUdpClient.h" /*** main.cpp ***/ vacUdpClient udpclient; QQmlContext* context = engine.rootContext(); context->setContextProperty("udpclient", &udpclient);
使用時候當(dāng)變量用就行,SCREEN_WIDTH
為變量名
//main.cpp #include <QGuiApplication> #include <QQmlApplicationEngine> #include <QLocale> #include <QTranslator> //全局變量必須得頭文件 #include <QQmlContext> int main(int argc, char *argv[]) { #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); #endif QGuiApplication app(argc, argv); QTranslator translator; const QStringList uiLanguages = QLocale::system().uiLanguages(); for (const QString &locale : uiLanguages) { const QString baseName = "untitled_" + QLocale(locale).name(); if (translator.load(":/i18n/" + baseName)) { app.installTranslator(&translator); break; } } QQmlApplicationEngine engine; //這兩句是重點,設(shè)置全局變量 QQmlContext *context = engine.rootContext(); context->setContextProperty("SCREEN_WIDTH", 800); const QUrl url(QStringLiteral("qrc:/main.qml")); QObject::connect( &engine, &QQmlApplicationEngine::objectCreated, &app, [url](QObject *obj, const QUrl &objUrl) { if (!obj && url == objUrl) QCoreApplication::exit(-1); }, Qt::QueuedConnection); engine.load(url); return app.exec(); }
//main.qml import QtQuick 2.15 import QtQuick.Window 2.15 import QtQuick.Controls 2.15 Window { id: window visible: true //使用全局變量 width: SCREEN_WIDTH height: 500 title: qsTr("Hello World") Button{ width: 100 height: 100 background: { color:"black" } } }
CPP訪問QML函數(shù)
//main.cpp #include <QGuiApplication> #include <QQmlApplicationEngine> #include <QLocale> #include <QTranslator> int main(int argc, char *argv[]) { #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); #endif QGuiApplication app(argc, argv); QTranslator translator; const QStringList uiLanguages = QLocale::system().uiLanguages(); for (const QString &locale : uiLanguages) { const QString baseName = "untitled_" + QLocale(locale).name(); if (translator.load(":/i18n/" + baseName)) { app.installTranslator(&translator); break; } } QQmlApplicationEngine engine; const QUrl url(QStringLiteral("qrc:/main.qml")); QObject::connect( &engine, &QQmlApplicationEngine::objectCreated, &app, [url](QObject *obj, const QUrl &objUrl) { if (!obj && url == objUrl) QCoreApplication::exit(-1); }, Qt::QueuedConnection); engine.load(url); //重點 auto list = engine.rootObjects(); auto window = list.first(); QVariant res; QVariant arg_1 = 123; QVariant arg_2 = "zhangsan"; QMetaObject::invokeMethod(window, "qmlFunc",Q_RETURN_ARG(QVariant, res),Q_ARG(QVariant, arg_1),Q_ARG(QVariant, arg_2)); qDebug() << "res = " << res; return app.exec(); }
//main.qml import QtQuick 2.15 import QtQuick.Window 2.15 import QtQuick.Controls 2.15 Window { id: window visible: true width: SCREEN_WIDTH height: 500 title: qsTr("Hello World") //供C++端調(diào)用的函數(shù) function qmlFunc(i, s) { return "success" } }
單實例注冊類
main.cpp文件里加這個
// qml單實例注冊 qmlRegisterSingletonInstance("PersonMudle", 1, 0, "MyPerson", &person);
以下這樣使用
import PersonMudle 1.0 Button { objectName: "qml_button" text: "QML button" font.pixelSize: 25 onClicked: { MyPerson.showInfo() } }
信號與槽
//加在main.cpp中 // engine 加載完成后 load以后 auto list = engine.rootObjects(); //auto objName = list.first()->objectName(); // 獲取第一個objname //auto mybuttonObj = list.first()->findChild<QObject *>("mybutton"); auto window = list.first(); //槽函數(shù)鏈接 // 第一個參數(shù)為組件 // 第二個為信號名 // 第三個為類的實例化 // 第三個為槽函數(shù) QObject::connect(window,SIGNAL(qmlSig(int,QString)), CppObject::getInstance(),SLOT(cppSlot(int,QString)));
例子:
//類 Person person("張三", 18); //上下文: 將類對象注冊到QML的上下文背景中 auto ctext = engine.rootContext(); ctext->setContextProperty("OtPerson", &person); //cpp獲取qml中的指定對象 auto rootObj = engine.rootObjects(); // rootObj.first()獲取所有對象列表 auto button = rootObj.first()->findChild<QObject*>("qml_button"); // 使用QT4的方式綁定信號和槽: qml的信號,cpp的槽 QObject::connect(button, SIGNAL(clicked()), &person, SLOT(clickButton())); QObject::connect(button, SIGNAL(coutNum(int)), &person, SLOT(clickCal(int))); /* // 使用QT5的方式綁定信號和槽不可行,此處button is nullptr auto button = rootObj.first()->findChild<QPushButton*>("qml_button"); if (!button) { qDebug() << "button is nullptr"; } QObject::connect(button, &QAbstractButton::clicked, &person, &Person::clieckButton); */
//main.qml import QtQuick 2.15 import QtQuick.Window 2.15 import QtQuick.Controls 2.15 as QtCtrl import QtQuick.Layouts 1.0 Window { width: 640 height: 480 visible: true title: qsTr("qml和cpp交互總結(jié)") Item { id: item anchors.fill: parent QtCtrl.Button { objectName: "qml_button" text: "QML button" font.pixelSize: 25 property int cal: 1 // qml中自定義信號 signal coutNum(int num) onClicked: { OtPerson.showInfo() if (0 == cal++ % 10) { coutNum(cal) } } } } }
到此這篇關(guān)于QML與CPP幾種交互方式的文章就介紹到這了,更多相關(guān)QML CPP交互內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
從string類的實現(xiàn)看C++類的四大函數(shù)(面試常見)
C++類一般包括構(gòu)造函數(shù)、拷貝構(gòu)造函數(shù)、析構(gòu)函數(shù)和賦值函數(shù)四大函數(shù),非常常見,本文給大家介紹從string類的實現(xiàn)看C++類的四大函數(shù),一起看看吧2016-06-06C/C++可變參數(shù)函數(shù)的實現(xiàn)
這篇文章主要介紹了C/C++可變參數(shù)函數(shù)的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04如何判斷一個數(shù)是否為2的冪次方?若是,并判斷出來是多少次方?
本篇文章是對如何判斷一個數(shù)是否為2的冪次方?若是,并判斷出來是多少次方的實現(xiàn)方法,進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05C++ vector容器 find erase的使用操作:查找并刪除指定元素
這篇文章主要介紹了C++ vector容器 find erase的使用操作:查找并刪除指定元素,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-05-05C語言每日練習(xí)之統(tǒng)計文本單詞數(shù)及高頻詞
本文文大家準(zhǔn)備了個C語言練習(xí)題:統(tǒng)計單詞數(shù)并找出頻率最高的單詞,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)C語言有一定幫助,感興趣的可以了解一下2022-05-05