QML與C++幾種交互方式
QML調(diào)用CPP函數(shù)
要求:
- 使用 Q_OBJECT 宏需要繼承 QObject 類。Q_OBJECT能夠啟用信號和槽機制、使用動態(tài)屬性系統(tǒng)。(使用 Q_OBJECT 宏的類需要通過Qt的元對象編譯器(moc)進行處理。)
- 使用 Q_INVOKABLE 修飾要暴露給 QML 的函數(shù)。
1.在main.cpp中進行注冊
// 注冊c++類到qml 參數(shù)分別為導入的 模塊名稱 主版本號 次版本號 模塊名稱
qmlRegisterType<CppObject>("CppObject",1,0,"CppObject");
2.在qml中導入
import CppObject 1.0
CppObject{
id:cppobj
}
3.通過id+方法名的方式調(diào)用
// 加上這個宏,當前函數(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;
}
}
//主要是這里其他的都是默認的
// 注冊c++類到qml 參數(shù)分別為導入的 模塊名稱 主版本號 次版本號 模塊名稱
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;
//這兩句是重點,設置全局變量
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);
使用時候當變量用就行,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;
//這兩句是重點,設置全局變量
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)
}
}
}
}
}到此這篇關于QML與CPP幾種交互方式的文章就介紹到這了,更多相關QML CPP交互內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
C/C++使用API實現(xiàn)數(shù)據(jù)的壓縮與解壓縮
在Windows編程中,經(jīng)常會遇到需要對數(shù)據(jù)進行壓縮和解壓縮的情況,本文將深入探討使用Windows API進行數(shù)據(jù)壓縮與解壓縮的過程,感興趣的小伙伴可以了解下2023-11-11
關于Visual Studio無法打開源文件"stdio.h"問題
這篇文章主要介紹了關于Visual Studio無法打開源文件"stdio.h"問題,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-04-04
C++實現(xiàn)LeetCode(889.由先序和后序遍歷建立二叉樹)
這篇文章主要介紹了C++實現(xiàn)LeetCode(889.由先序和后序遍歷建立二叉樹),本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下2021-07-07
C語言中的abs()函數(shù)和exp()函數(shù)的用法
這篇文章主要介紹了C語言中的abs()函數(shù)和exp()函數(shù)的用法,是C語言入門學習中的基礎知識,需要的朋友可以參考下2015-08-08
Vscode配置C/C++環(huán)境使用minGW(保姆級配置過程)
本文主要介紹了Vscode配置C/C++環(huán)境使用minGW(保姆級配置過程),文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-02-02

