QML與C++交互之創(chuàng)建自定義對(duì)象的實(shí)現(xiàn)
在qml中,我們一般都是希望使用qml做界面展示,而數(shù)據(jù)處理轉(zhuǎn)由c++處理;
在此篇博客,將介紹如何在c++中給qml定義全局對(duì)象;在c++中如何定義對(duì)象給qml使用。
1 給qml定義全局對(duì)象
正常我們定義了一個(gè)qml項(xiàng)目后,main函數(shù)是這樣的:
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
return app.exec();
}QQmlApplicationEngine 是 Qt 框架中用于加載和運(yùn)行基于 QML 的應(yīng)用程序的核心類,結(jié)合了 QQmlEngine 和 QQmlComponent 的功能,支持從單個(gè) QML 文件加載應(yīng)用程序,并實(shí)現(xiàn) C++ 與 QML 的雙向通信。
那么,就可以使用QQmlApplicationEngine去獲得全局上下文對(duì)象QQmlContext,通過使用上下文對(duì)象,就可以給qml設(shè)置一個(gè)全局的變量值;
獲得上下文對(duì)象:
// 獲得全局對(duì)象,上下文對(duì)象 QQmlContext *context = engine.rootContext();
給qml設(shè)置一個(gè)全局變量:
// 給qml設(shè)置一個(gè)全局變量;
context->setContextProperty("SCREEN_WIDTH", 800);這樣,就可以在qml中使用該變量了,例如在mian.qml文件內(nèi)使用:
import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 2.14
Window {
id: root
visible: true
width: SCREEN_WIDTH // 直接使用
height: 500
title: qsTr("Hello World")
color: "white"
// 如果qml內(nèi)部有定義重名變量,那么會(huì)優(yōu)先使用qml內(nèi)部定義的變量,而不會(huì)使用C++定義的變量
//property int SCREEN_WIDTH: 500
}
注意:如果qml內(nèi)部有定義重名變量,那么會(huì)優(yōu)先使用qml內(nèi)部定義的變量;另外,定義全局變量會(huì)有性能消耗問題。
2 在c++中定義對(duì)象給qml使用
自定義C++類MyObject繼承自QObject;有兩個(gè)成員變量,int m_iValue 和 QString m_sString;并且給他倆定義get和set方法;另外在定義兩個(gè)信號(hào);最后通過Q_PROPERTY將兩個(gè)成員變量暴露給元對(duì)象。
myobject.h
#ifndef MYOBJECT_H
#define MYOBJECT_H
#include <QObject>
class MyObject : public QObject
{
Q_OBJECT
public:
MyObject(QObject *parent = nullptr); // 構(gòu)造函數(shù)
~MyObject();
const int &iValue() const;
void setIIValue(const int &newIValue);
const QString &sString() const;
void setSString(const QString &newSString);
signals:
void iValueChanged();
void sStringChanged();
private:
int m_iValue;
QString m_sString;
Q_PROPERTY(int iValue READ iValue WRITE setIIValue NOTIFY iValueChanged)
// Q_PROPERTY(QString sString READ sString WRITE setSString NOTIFY sStringChanged)
// 如果值是函數(shù)內(nèi)部成員變量的值,可使用MEMBER去設(shè)置,與READ sString WRITE setSString實(shí)現(xiàn)效果一致
Q_PROPERTY(QString sString MEMBER m_sString NOTIFY sStringChanged)
};
#endif // MYOBJECT_Hmyobject.cpp
#include "myobject.h"
MyObject::MyObject(QObject *parent) : QObject(parent)
{
}
MyObject::~MyObject()
{
}
const int &MyObject::iValue() const
{
return m_iValue;
}
void MyObject::setIIValue(const int &newIValue)
{
if (m_iValue == newIValue) {
return;
}
m_iValue = newIValue;
emit iValueChanged();
}
const QString &MyObject::sString() const
{
return m_sString;
}
void MyObject::setSString(const QString &newSString)
{
if (m_sString == newSString) {
return;
}
m_sString = newSString;
emit sStringChanged();
}Q_PROPERTY的參數(shù)講解
Q_PROPERTY(int iValue READ iValue WRITE setIIValue NOTIFY iValueChanged)
int iValue 指定是給qml使用的變量名,推薦與c++類成員變量名類似;
READ iValue 指的是通過iValue函數(shù)去讀取值;
WRITE setIIValue 指的是通過setIIValue函數(shù)去修改iValue值;
NOTIFY iValueChanged 指的是當(dāng)iValue值被修改后,會(huì)發(fā)送的信號(hào);
然后main函數(shù)中使用qmlRegisterType函數(shù)對(duì)自定義類進(jìn)行注冊(cè),注冊(cè)后,就可以在qml那邊導(dǎo)入使用了。
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include "myobject.h"
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
// 獲得全局對(duì)象,上下文對(duì)象
QQmlContext *context = engine.rootContext();
// 給qml設(shè)置一個(gè)全局變量;如果qml內(nèi)部有定義重名變量,那么會(huì)優(yōu)先使用qml內(nèi)部定義的變量;另外,定義全局變量會(huì)有性能問題
context->setContextProperty("SCREEN_WIDTH", 800);
// 注冊(cè),在需要使用的地方 import MyObj 1.0
qmlRegisterType<MyObject>("MyObj", 1, 0, "MyObject");
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
return app.exec();
}其中,MyObj是給qml那邊導(dǎo)入時(shí)使用的模塊名字,1 和 0 指的是版本,最后的MyObject就是自定義類名;
然后就可以在qml中 import MyObj 1.0 導(dǎo)入使用了。
import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 2.14
import MyObj 1.0 // 導(dǎo)入自定義模塊
Window {
id: root
visible: true
width: SCREEN_WIDTH
height: 500
title: qsTr("Hello World")
color: "white"
MyObject {
iValue: 20
sString: "this is a custom obj.";
Component.onCompleted: {
console.log("iValue:", 20, " sString:", sString)
}
}
}
3 番外
Q_PROPERTY為什么要指定NOTIFY信號(hào)呢?
在這里與qml的綁定有關(guān)系;
在qml中,當(dāng)給一個(gè)變量以冒號(hào)':'方式賦值時(shí),這兩個(gè)變量是互相綁定的;例如:
property int testValue: myObj.iValue
當(dāng)myObj.iValue被修改時(shí),就會(huì)觸發(fā)信號(hào)通知testValue也一并修改!
案例代碼:定義變量testValue使用冒號(hào)被myObject.iValue賦值,定義按鈕在onClicked槽函數(shù)中修改myObj.iValue值,觀察testValue是否也被修改;
import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 2.14
import MyObj 1.0 // 導(dǎo)入自定義模塊
Window {
id: root
visible: true
width: SCREEN_WIDTH
height: 500
title: qsTr("Hello World")
color: "white"
property int testValue: myObj.iValue // 綁定了
onTestValueChanged: {
console.log("testValue:", testValue)
}
Button {
width: 100; height: 50
onClicked: {
myObj.iValue = 50;
}
}
MyObject {
id: myObj
iValue: 20
sString: "this is a custom obj.";
Component.onCompleted: {
console.log("iValue:", 20, " sString:", sString)
}
}
}當(dāng)點(diǎn)擊按鈕后,修改的是myObj.iValue,但testValue也一并被修改了,由此證明,使用冒號(hào)賦值時(shí),他倆是會(huì)綁定在一起的。

注意,使用 = 賦值時(shí),不會(huì)有綁定的效果!??!
到此這篇關(guān)于QML與C++交互之創(chuàng)建自定義對(duì)象的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)QML與C++交互內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Qt6 QML實(shí)現(xiàn)DateTimePicker組件的示例代碼
- Qt?QML實(shí)現(xiàn)無(wú)邊框窗口的實(shí)例代碼
- Qt6+QML實(shí)現(xiàn)Windows屏幕錄制功能
- Qt?Qml實(shí)現(xiàn)毛玻璃效果
- Qt qml實(shí)現(xiàn)動(dòng)態(tài)輪播圖效果
- 基于Qml實(shí)現(xiàn)水印工具
- QML與C++幾種交互方式
- Qt QML使用虛擬鍵盤的示例代碼
- C++與QML進(jìn)行數(shù)據(jù)交互的常見方法總結(jié)
- C++與QML交互的項(xiàng)目實(shí)踐
- Qt6 QML Flickable控件詳解
相關(guān)文章
C++實(shí)現(xiàn)教職工信息管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)教職工信息管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03
C語(yǔ)言連接并操作Sedna XML數(shù)據(jù)庫(kù)的方法
這篇文章主要介紹了C語(yǔ)言連接并操作Sedna XML數(shù)據(jù)庫(kù)的方法,實(shí)例分析了C語(yǔ)言操作XML文件的相關(guān)技巧,需要的朋友可以參考下2015-06-06
C語(yǔ)言動(dòng)態(tài)數(shù)組的使用實(shí)現(xiàn)代碼
這篇文章主要介紹了C語(yǔ)言動(dòng)態(tài)數(shù)組的使用實(shí)現(xiàn)代碼的相關(guān)資料,需要的朋友可以參考下2017-01-01
淺談內(nèi)聯(lián)函數(shù)與宏定義的區(qū)別詳解
本篇文章是對(duì)內(nèi)聯(lián)函數(shù)與宏定義的區(qū)別進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05
深入理解C++中的new/delete和malloc/free動(dòng)態(tài)內(nèi)存管理及區(qū)別介紹
這篇文章主要介紹了深入理解C++中的new/delete和malloc/free動(dòng)態(tài)內(nèi)存管理,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-09-09
詳解如何從Matlab中導(dǎo)出清晰的結(jié)果圖片
寫文章的時(shí)候有時(shí)需要matlab導(dǎo)出清晰的圖片,如果直接用figure里面的保存的話不夠清晰,下面這篇文章主要給大家介紹了關(guān)于如何從Matlab中導(dǎo)出清晰的結(jié)果圖片的相關(guān)資料,需要的朋友可以參考下2022-06-06
Qt QChart 創(chuàng)建圖表的實(shí)現(xiàn)方法
這篇文章主要介紹了Qt QChart 創(chuàng)建圖表的實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12

