qml与c++数据交互
1.01 方式一:qmlRegisterType() 注册新的 C++ 类型、允许 QML 创建和使用自定义类型。
#include <QObject>
class MyItem : public QObject
{
Q_OBJECT
Q_PROPERTY(QString name READ getName WRITE setName NOTIFY nameChangeSig)
public:
explicit MyItem(QObject *parent = nullptr) : QObject(parent), m_strItemName(""){}
void setName(QString name) {
if(m_strItemName != name)
{
m_strItemName = name;
emit nameChangeSig();
}
}
QString getName(){
return m_strItemName;
}
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);
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
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
onNameChangeSig: {
console.log('qml Name Changed')
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 指令来定义一个单例类型
- 使用场景
共享状态: 在整个应用程序中共享状态或配置。
资源管理: 管理公共资源,如数据库连接、网络客户端等。
全局设置: 提供全局的设置和配置选项。
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;
}
);
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通