QML與C++幾種交互方式
QML調(diào)用CPP函數(shù)
要求:
- 使用 Q_OBJECT 宏需要繼承 QObject 類。Q_OBJECT能夠啟用信號(hào)和槽機(jī)制、使用動(dòng)態(tài)屬性系統(tǒng)。(使用 Q_OBJECT 宏的類需要通過Qt的元對(duì)象編譯器(moc)進(jìn)行處理。)
- 使用 Q_INVOKABLE 修飾要暴露給 QML 的函數(shù)。
1.在main.cpp中進(jìn)行注冊(cè)
// 注冊(cè)c++類到qml 參數(shù)分別為導(dǎo)入的 模塊名稱 主版本號(hào) 次版本號(hào) 模塊名稱
qmlRegisterType<CppObject>("CppObject",1,0,"CppObject");
2.在qml中導(dǎo)入
import CppObject 1.0
CppObject{
id:cppobj
}
3.通過id+方法名的方式調(diào)用
// 加上這個(gè)宏,當(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è)c++類到qml 參數(shù)分別為導(dǎo)入的 模塊名稱 主版本號(hào) 次版本號(hà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")
}
}
}
定義全局變量,注冊(cè)到上下文
樣例:
#include <QQmlContext>
QQmlApplicationEngine engine;
//這兩句是重點(diǎn),設(shè)置全局變量
QQmlContext *context = engine.rootContext();
context->setContextProperty("SCREEN_WIDTH", 800);
也可以用此方法將類對(duì)象暴露給QMLsetContextProperty兩個(gè)參數(shù)表示的意義為:
- 第一個(gè)參數(shù)表示 qml 可以識(shí)別的對(duì)象名
- 第二個(gè)參數(shù)表示 C++ 對(duì)象
#include <QtQml/QQmlContext>
#include "vacUdpClient.h"
/*** main.cpp ***/
vacUdpClient udpclient;
QQmlContext* context = engine.rootContext();
context->setContextProperty("udpclient", &udpclient);
使用時(shí)候當(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;
//這兩句是重點(diǎn),設(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);
//重點(diǎn)
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"
}
}
單實(shí)例注冊(cè)類
main.cpp文件里加這個(gè)
// qml單實(shí)例注冊(cè)
qmlRegisterSingletonInstance("PersonMudle", 1, 0, "MyPerson", &person);
以下這樣使用
import PersonMudle 1.0
Button {
objectName: "qml_button"
text: "QML button"
font.pixelSize: 25
onClicked: {
MyPerson.showInfo()
}
}
信號(hào)與槽
//加在main.cpp中
// engine 加載完成后 load以后
auto list = engine.rootObjects();
//auto objName = list.first()->objectName(); // 獲取第一個(gè)objname
//auto mybuttonObj = list.first()->findChild<QObject *>("mybutton");
auto window = list.first();
//槽函數(shù)鏈接
// 第一個(gè)參數(shù)為組件
// 第二個(gè)為信號(hào)名
// 第三個(gè)為類的實(shí)例化
// 第三個(gè)為槽函數(shù)
QObject::connect(window,SIGNAL(qmlSig(int,QString)),
CppObject::getInstance(),SLOT(cppSlot(int,QString)));
例子:
//類
Person person("張三", 18);
//上下文: 將類對(duì)象注冊(cè)到QML的上下文背景中
auto ctext = engine.rootContext();
ctext->setContextProperty("OtPerson", &person);
//cpp獲取qml中的指定對(duì)象
auto rootObj = engine.rootObjects();
// rootObj.first()獲取所有對(duì)象列表
auto button = rootObj.first()->findChild<QObject*>("qml_button");
// 使用QT4的方式綁定信號(hào)和槽: qml的信號(hào),cpp的槽
QObject::connect(button, SIGNAL(clicked()), &person, SLOT(clickButton()));
QObject::connect(button, SIGNAL(coutNum(int)), &person, SLOT(clickCal(int)));
/*
// 使用QT5的方式綁定信號(hào)和槽不可行,此處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中自定義信號(hào)
signal coutNum(int num)
onClicked: {
OtPerson.showInfo()
if (0 == cal++ % 10) {
coutNum(cal)
}
}
}
}
}到此這篇關(guān)于QML與CPP幾種交互方式的文章就介紹到這了,更多相關(guān)QML CPP交互內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語(yǔ)言鏈表實(shí)現(xiàn)學(xué)生成績(jī)管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言鏈表實(shí)現(xiàn)學(xué)生成績(jī)管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-07-07
C/C++使用API實(shí)現(xiàn)數(shù)據(jù)的壓縮與解壓縮
在Windows編程中,經(jīng)常會(huì)遇到需要對(duì)數(shù)據(jù)進(jìn)行壓縮和解壓縮的情況,本文將深入探討使用Windows API進(jìn)行數(shù)據(jù)壓縮與解壓縮的過程,感興趣的小伙伴可以了解下2023-11-11
關(guān)于Visual Studio無(wú)法打開源文件"stdio.h"問題
這篇文章主要介紹了關(guān)于Visual Studio無(wú)法打開源文件"stdio.h"問題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-04-04
OpenCV實(shí)現(xiàn)圖像的直線檢測(cè)
這篇文章主要為大家詳細(xì)介紹了OpenCV實(shí)現(xiàn)圖像直線檢測(cè)的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-01-01
C++實(shí)現(xiàn)LeetCode(889.由先序和后序遍歷建立二叉樹)
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(889.由先序和后序遍歷建立二叉樹),本篇文章通過簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07
C語(yǔ)言中的abs()函數(shù)和exp()函數(shù)的用法
這篇文章主要介紹了C語(yǔ)言中的abs()函數(shù)和exp()函數(shù)的用法,是C語(yǔ)言入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2015-08-08
Vscode配置C/C++環(huán)境使用minGW(保姆級(jí)配置過程)
本文主要介紹了Vscode配置C/C++環(huán)境使用minGW(保姆級(jí)配置過程),文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-02-02

