qml與c++數據交互
1.01 方式一:qmlRegisterType() 注冊新的 C++ 類型、允許 QML 創建和使用自定義類型。
//1.0 c++類中使用Q_PROPERTY宏定義屬性,使用綁定語法將屬性與QML元素關聯
#include <QObject>
class MyItem : public QObject
{
Q_OBJECT
/* 使用 Q_PROPERTY 定義交互的屬性 */
Q_PROPERTY(QString name READ getName WRITE setName NOTIFY nameChangeSig)
public:
explicit MyItem(QObject *parent = nullptr) : QObject(parent), m_strItemName(""){}
/* 為屬性提供 getter 和 setter 方法 */
void setName(QString name) {
if(m_strItemName != name)
{
m_strItemName = name;
emit nameChangeSig();
}
}
QString getName(){
return m_strItemName;
}
/* 將自定義 C++ 類型注冊到 QML 中的函數*/
static void registerQmlType(){
qmlRegisterType<MyItem>("qmlMyItem", 1, 0, "MyItem");
}
private:
QString m_strItemName;
signals:
/* 信號與屬性對應,通過信號通知其他對象屬性的變化 */
void nameChangeSig();
public slots:
void slotNameChange();
};
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlEngine>
#include "myitem.h"
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
/* 將自定義 C++ 類型注冊到 QML 中的函數*/
//qmlRegisterType<MyItem>("qmlMyItem", 1, 0, "MyItem");
MyItem::registerQmlType();
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();
}
import QtQuick 2.12
import QtQuick.Window 2.12
/*引入c++類*/
import qmlMyItem 1.0
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
Rectangle{
width: 50; height: 50;
color: 'red'
MouseArea {
anchors.fill: parent
onClicked: myItem.name = 'li'
}
}
MyItem {
id:myItem
/*qml值改變,觸發事件*/
onNameChangeSig: {
console.log('qml Name Changed')
/*qml中通知c++對象*/
myItem.slotNameChange()
}
}
}
1.02 qml中調用c++對象方法, 使用Q_INVOKABLE宏定義函數
(1) 在c++類中通過Q_INVOKABLE聲明函數:
Q_INVOKABLEvoid setByName (QString name){m_strItemName = name;}
(2) 在qml中直接使用
myItem.setByName('xiaoming')
2.01 方式二:engine->rootContext()->setContextProperty(),注冊單個對象實例、暴露特定的對象實例給 QML
// 在類中定義注冊接口
void MainConfig::registerQml( QQmlEngine *engine ) {
engine->rootContext()->setContextProperty( "MainConfig", this );
}
---------------------------------------------------------------
MainConfig::Instance()->registerQml( _engine );
Text {
text: "應用程序名稱: " + MainConfig.appName
font.pixelSize: 18
Layout.alignment: Qt.AlignHCenter
}
對比總結
| 特性 |
engine->rootContext()->setContextProperty() |
qmlRegisterType() |
| 目的 |
注冊單個對象實例 |
注冊新的 C++ 類型 |
| 使用場景 |
暴露特定的對象實例給 QML |
允許 QML 創建和使用自定義類型 |
| 訪問方式 |
通過對象名稱訪問屬性和方法 |
通過類型名稱創建實例并訪問屬性和方法 |
| 生命周期管理 |
需要手動管理對象的生命周期 |
自動管理注冊類型的生命周期 |
| 靈活性 |
更適合單一對象的交互 |
更適合多個實例的創建和管理 |
3.01 c++中的枚舉在qml中注冊使用
- 用于在 QML 中注冊一個不可創建的 C++ 枚舉類型或命名空間。
- 允許 QML 訪問枚舉值或常量,但不能直接實例化該元對象。
- 適用于組織和管理全局常量和枚舉類型。
namespace MyNamespace {
Q_NAMESPACE
enum MyEnum {
Key1,
Key2,
};
Q_ENUM_NS(MyEnum)
}
// 在類中定義注冊接口
void MainConfig::registerQml( QQmlEngine *engine ) {
engine->rootContext()->setContextProperty( "MainConfig", this );
qmlRegisterUncreatableMetaObject(MyNamespace::staticMetaObject, "io.qt", 1, 0, "MyNamespace",
"Access to enums & flags only");
}
4.01 在 QML 文件中使用 pragma Singleton 指令來定義一個單例類型
- 使用場景
共享狀態: 在整個應用程序中共享狀態或配置。
資源管理: 管理公共資源,如數據庫連接、網絡客戶端等。
全局設置: 提供全局的設置和配置選項。
// appVersionSingleton.qml
pragma Singleton
import QtQuick 2.15
QtObject {
property string appName: "appVersionSingleton"
property int version: 1
function getApplicationInfo() {
return `${appName} v${version}`;
}
}
// 注冊單例類型
qmlRegisterSingletonType<QObject>(
"com.appversion.singleton",
1,
0,
"appVersion",
[](QQmlEngine *, QJSEngine *) -> QObject* {
static QObject instance;
return &instance;
}
);