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)文章希望大家以后多多支持腳本之家!
- Qt6 QML實(shí)現(xiàn)DateTimePicker組件的示例代碼
- Qt?QML實(shí)現(xiàn)無邊框窗口的實(shí)例代碼
- QML與C++交互之創(chuàng)建自定義對(duì)象的實(shí)現(xiàn)
- Qt6+QML實(shí)現(xiàn)Windows屏幕錄制功能
- Qt?Qml實(shí)現(xiàn)毛玻璃效果
- Qt qml實(shí)現(xiàn)動(dòng)態(tài)輪播圖效果
- 基于Qml實(shí)現(xiàn)水印工具
- Qt QML使用虛擬鍵盤的示例代碼
- C++與QML進(jìn)行數(shù)據(jù)交互的常見方法總結(jié)
- C++與QML交互的項(xiàng)目實(shí)踐
- Qt6 QML Flickable控件詳解
相關(guān)文章
C/C++函數(shù)參數(shù)傳遞機(jī)制詳解及實(shí)例
這篇文章主要介紹了C/C++函數(shù)參數(shù)傳遞機(jī)制詳解及實(shí)例的相關(guān)資料,需要的朋友可以參考下2017-02-02
C語言中isalnum()函數(shù)和isalpha()函數(shù)的對(duì)比使用
這篇文章主要介紹了C語言中isalnum()函數(shù)和isalpha()函數(shù)的對(duì)比使用,都可以判斷是否為字母但isalnum的判斷還包括數(shù)字,需要的朋友可以參考下2015-08-08
C++中的繼承問題(繼承基本概念、菱形虛擬繼承的對(duì)象模型)
這篇文章主要介紹了C++中的繼承問題(繼承基本概念、菱形虛擬繼承的對(duì)象模型),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-02-02
C++ main函數(shù)中的argc與argv全面解析
C/C++中的main函數(shù)可以接受命令行參數(shù),通過argc和argv來傳遞這些參數(shù),argc表示參數(shù)總數(shù),argv是一個(gè)字符串?dāng)?shù)組,包含具體的參數(shù),本文介紹C++ main函數(shù)中的argc與argv,感興趣的朋友跟隨小編一起看看吧2026-03-03
C語言實(shí)現(xiàn)學(xué)生選修課程系統(tǒng)設(shè)計(jì)
這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)學(xué)生選修課程系統(tǒng)設(shè)計(jì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-02-02
C語言字符函數(shù)isalnum()和iscntrl()詳解
大家好,本篇文章主要講的是C語言字符函數(shù)isalnum()和iscntrl()詳解,感興趣的同學(xué)趕快來看一看吧,對(duì)你有幫助的話記得收藏一下2022-02-02

