惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Y
Y Combinator Blog
The GitHub Blog
The GitHub Blog
Vercel News
Vercel News
D
DataBreaches.Net
MongoDB | Blog
MongoDB | Blog
H
Help Net Security
小众软件
小众软件
美团技术团队
T
The Blog of Author Tim Ferriss
爱范儿
爱范儿
D
Docker
Martin Fowler
Martin Fowler
大猫的无限游戏
大猫的无限游戏
博客园 - 聂微东
Blog — PlanetScale
Blog — PlanetScale
H
Hackread – Cybersecurity News, Data Breaches, AI and More
罗磊的独立博客
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
V
V2EX
S
SegmentFault 最新的问题
云风的 BLOG
云风的 BLOG
B
Blog
雷峰网
雷峰网
The Cloudflare Blog

博客园 - osbreak

ros2::tf2 k8s:: Service 管理 deployment postgresql 索引 postgresql 基本类型 postgresql 基础运维 PLSQL 触发器 PLSQL 程序包 PLSQL 执行块 PLSQL 基础数据类型 PLSQL oracle安装部署 mysql事务与隔离 mysql慢查询分析 mysql建增删改查 mysql常用总结 (9)libevent 常用设置 (8)libevent 构建libevent http服务,支持文件下载 (7)libevent filter(过滤器) (6)libevent定时器 (5)libevent evbuffer
QML::qml与c++数据交互
osbreak · 2024-03-23 · via 博客园 - osbreak

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;
	}
);