QML与C++交互
QML 与 C++ 的交互是 Qt Quick 开发的核心需求,常用于将界面逻辑与底层业务逻辑解耦。一、基础交互机制元对象系统(Meta-Object System):基于 Qt 的 moc(元对象编译器)生成反射信息,实现 QML 与 C++ 的双向通信,依赖信号槽(Signals Slots)和属性绑定(Property Binding)‌。QML 引擎:通过 QQmlEngine 解析 QML 并建立与 C++ 的连接数据类型映射‌:QML 自动转换基础类型(如int、QString),复杂类型需注册为元类型(如QJsonObject)‌在 Qt 的 QML/C++ 集成中,qmlRegisterType和setContextProperty是两种将 C++ 对象暴露给 QML 的主要方式,它们有显著的不同和使用场景。区别对比特性qmlRegisterTypesetContextProperty用途注册类型,允许在 QML 中创建新实例暴露特定对象实例到 QML 上下文对象生命周期由 QML 引擎管理由 C++ 控制QML 中的使用方式可以创建多个实例 (Person {})直接访问固定实例 (globalPerson)典型应用场景可复用的组件类全局单例、应用配置等版本控制支持 (通过 uri 和版本号)不支持线程安全性自动处理需要手动确保线程安全二、C++ 暴露给 QML1. 注册上下文属性cpp// main.cpp QQmlApplicationEngine engine; QString hello = "World"; // 设置上下文属性 engine.rootContext()-setContextProperty("helloText", hello); // QML 中直接使用 // Text { text: helloText }2. 注册 C++ 类型cpp// person.h class Person : public QObject { Q_OBJECT Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) public: // ... 属性和方法实现 }; // main.cpp qmlRegisterTypePerson("People", 1, 0, "Person"); // QML 中使用 // import People 1.0 // Person { name: "Alice" }Q_PROPERTY是 Qt 中连接 C++ 后端与 QML 前端的关键机制,它允许将 C++ 类的成员变量作为属性暴露给 QML 使用。Q_PROPERTY(type name READ getFunction [WRITE setFunction] [NOTIFY signal] [OTHER_OPTIONS])3. 使用 Q_INVOKABLEcppclass Calculator : public QObject { Q_OBJECT public: Q_INVOKABLE int add(int a, int b) { return a + b; } }; // QML 中调用 // calculator.add(2, 3)Q_INVOKABLE是 Qt 提供的一个宏,用于标记 C++ 成员函数可以从 QML 或 Qt 的元对象系统(如信号槽)中调用。public slots函数也可以从 QML 中调用。核心区别特性Q_INVOKABLEpublic slots调用方式直接函数调用信号槽机制或直接调用性能略高(直接调用)略低(经过元对象系统)使用场景任何需要暴露给QML的函数主要用于信号连接信号连接不能作为槽接收信号可以作为槽接收信号返回值支持支持参数类型必须是QVariant支持的类型必须是QVariant支持的类型示例:#include QObject class MyClass : public QObject { Q_OBJECT public: // 普通成员函数 - QML 不可见 void normalFunction(); // QML 可调用的函数 Q_INVOKABLE void invokableFunction(); // 带返回值的可调用函数 Q_INVOKABLE QString getInfo(); // 带参数的可调用函数 Q_INVOKABLE void setValue(int value); };4. 暴露一个对象(包含了多个成员类)使用Q_PROPERTY定义类变量,这个需要使用指针变量。#MyObject.h #HistoryModel一个模型自定义类 struct LeakInputFileInfo { QString name; long long fileSize; QString filePath; int type; QString lastModifyDatetime; QString keyName; bool selected; }; // 注册元类型 Q_DECLARE_METATYPE(LeakInputFileInfo) class HistoryModel: public QAbstractListModel { Q_OBJECT public: enum Roles { NameRole = Qt::UserRole + 1, FileSizeRole, FilePathRole, TypeRole, LastModifyDatetimeRole, selectedRole, keyNameRole }; explicit HistoryModel(QObject *parent = nullptr); //需要实现的方法 int rowCount(const QModelIndex parent = QModelIndex()) const override; QVariant data(const QModelIndex index, int role = Qt::DisplayRole) const override; QHashint, QByteArray roleNames() const override; //设置数据 Q_INVOKABLE void updateData(QListLeakInputFileInfo inputData); //获取数量 Q_INVOKABLE int getHistoryFileCount(); Q_INVOKABLE void setSelected(int row, bool selected); Q_INVOKABLE bool isSelected(int row); protected: QListLeakInputFileInfo m_data; } //HistoryModel是类定义,自己去实现。 int HistoryModel::rowCount(const QModelIndex parent) const { Q_UNUSED(parent) return parent.isValid() ? 0 : m_data.size(); } QVariant HistoryModel::data(const QModelIndex index, int role) const { if (!index.isValid() || index.row() = m_data.size()) return QVariant(); const auto item = m_data.at(index.row()); switch (role) { case NameRole: return item.name; case FileSizeRole: return item.fileSize; case FilePathRole: return item.filePath; case TypeRole: return item.type; case LastModifyDatetimeRole: return item.lastModifyDatetime; case selectedRole: return item.selected; case keyNameRole: return item.keyName; default: return QVariant(); } } QHashint, QByteArray HistoryModel::roleNames() const { return { {NameRole, "name"}, {FileSizeRole, "fileSize"}, {FilePathRole, "filePath"}, {TypeRole, "type"}, {LastModifyDatetimeRole, "lastModifyDatetime"}, {selectedRole, "selected"}, {keyNameRole, "keyName"} }; } //设置数据 void HistoryModel::updateData(QListLeakInputFileInfo inputData) { beginResetModel(); m_data = inputData; endResetModel(); } int HistoryModel::getHistoryFileCount() { return m_data.size(); } void HistoryModel::setSelected(int row, bool selected) { if (row 0 || row = m_data.size()) return; if (m_data[row].selected == selected) return; // 状态未变,无需更新 m_data[row].selected = selected; // 通知视图该行数据已更改(只刷新 selected 角色) QModelIndex idx = index(row); emit dataChanged(idx, idx, { selectedRole }); } bool HistoryModel::isSelected(int row) { if (row 0 || row = m_data.size()) return false; return m_data[row].selected; } #MyObject class MyObject: public QObject { Q_OBJECT Q_PROPERTY(HistoryModel* historyModel READ historyModel CONSTANT) Q_PROPERTY(QStringListModel* newModel READ newModel CONSTANT) public: explicit MyObject(QObject *parent = nullptr); HistoryModel* historyModel() const; QStringListModel * newModel() const; Q_INVOKABLE int getFileCount(); public: HistoryModel* m_historyModel; QStringListModel * m_newModel; } #MyObject.cpp MyObject::MyObject(QObject *parent) : QObject{parent} { m_historyModel = new HistoryModel(); m_newModel = new QStringListModel(); } MyObject* MyObject::historyModel() const { return m_historyModel ; } MyObject* MyObject::newModel() const { return m_newModel; } int MyObject::getFileCount() { return 100; }注册// main.cpp QQmlApplicationEngine engine; //qRegisterMetaTypeHistoryModel*("HistoryModel*"); MyObject myObject; // 设置上下文属性 engine.rootContext()-setContextProperty("MO_Object", myObject);

相关新闻

TVA-World架构:在工业质检中小试牛刀(6)

TVA-World架构:在工业质检中小试牛刀(6)

前沿技术探索:TVA智能体(简称TVA)TVA智能体(亦称“AI智能体视觉”或“TVA视觉智能体”)是依托Transformer架构与“因式智能体”理论构建的系统级视觉技术框架。它融合深度强化学习(DRL)、卷积神…

2026/8/18 18:45:03 阅读更多 →
智能代码审查上线后,前端该盯哪些信号

智能代码审查上线后,前端该盯哪些信号

智能代码审查上线后,前端该盯哪些信号 AI 代码生成和智能审查接入 CI 后,最难排查的往往不是模型是否返回了内容,而是请求究竟卡在哪一段:上下文提取、网关转发、流式传输,还是本地校验。只记录“请求超时”通常不足以…

2026/8/18 18:44:03 阅读更多 →
FreeRTOS从入门到精通:任务调度、内存管理与调试实战

FreeRTOS从入门到精通:任务调度、内存管理与调试实战

1. 为什么是FreeRTOS?一个嵌入式老兵的视角 如果你刚开始接触嵌入式实时操作系统,或者刚从裸机编程转向RTOS,面对FreeRTOS、RT-Thread、μC/OS这些名字,可能会有点懵。我当年也一样。今天,我想从一个嵌入式开发者的角度…

2026/8/18 18:44:03 阅读更多 →

最新新闻

QUICK:GPU 加速的 ab initio / DFT 开源量子化学包—原理、安装实测与横向对比

QUICK:GPU 加速的 ab initio / DFT 开源量子化学包—原理、安装实测与横向对比

QUICK 是 UCSD Gtz Lab 与 Michigan State Merz Lab 联合开发的开源量子化学包,主打 GPU-native HF / DFT 计算、MPI 多卡扩展、内置 QM/MM 接口(与 AmberTools 26 直接集成)。专注于 HF/DFT 计算、几何优化、RESP 电荷和 QM/MM 模拟。最新版本 QUICK-26.03(2026-07-25)已…

2026/8/18 20:39:10 阅读更多 →
九种天气下的蓝调通勤:亚洲成年女性高清提示词实验

九种天气下的蓝调通勤:亚洲成年女性高清提示词实验

封面只负责建立系列节奏;正文保留九张独立高清竖图。 摘要| 同样是蓝色,春雨、干雷雨、海雾、轻雪、太阳雨、季风、秋风、霜冻和雨后蓝调会给面料完全不同的亮度与情绪。本组用九位约 22 岁亚洲成年女性、九种面孔与焦段,完成 5 套…

2026/8/18 20:39:10 阅读更多 →
AI 查库为什么要先做权限交集,再让模型看 Schema?

AI 查库为什么要先做权限交集,再让模型看 Schema?

先确定谁能看什么,再让模型生成 SQL;顺序本身就是安全边界。 摘要| 把数据库结构整包交给模型,再对生成 SQL 做一次关键词过滤,看起来省事,实际上把越权风险提前送进了提示词。本文结合 Microi吾码AI 当前 …

2026/8/18 20:39:10 阅读更多 →
干货:18 张思维导图,后端技术学习路线长这样!

干货:18 张思维导图,后端技术学习路线长这样!

1946年, 世界上第一台名叫「ENIAC」的通用计算机被发明出来, 它正如其名字那般仅仅是用来计算的。后来, 计算机数量变得越来越多起来, 当没有网络的时候, 每一台计算机都将会变成一个孤岛, 如此也就不会有如今互联网的那种繁荣景象了。「计算机网络」这门课程的学习路线是极为清…

2026/8/18 20:39:10 阅读更多 →
利用多台老旧笔记本搭建分布式集群,低成本本地部署800亿参数大模型

利用多台老旧笔记本搭建分布式集群,低成本本地部署800亿参数大模型

这次我们来看一个非常硬核的本地AI部署方案:用多台老旧笔记本搭建一个分布式计算集群,来运行参数量高达800亿(80B)的大语言模型。这个项目的核心思路不是追求单卡的极致性能,而是通过资源整合,让那些被淘汰…

2026/8/18 20:39:10 阅读更多 →
重构复杂条件逻辑:状态模式与策略模式实战

重构复杂条件逻辑:状态模式与策略模式实战

1. 为什么我们需要重构if/switch语句在代码维护过程中,我们经常会遇到这样的场景:一个方法里嵌套着七八层if判断,或者一个switch语句横跨上百行代码。这种代码结构不仅难以阅读和维护,还会带来一系列实际问题。我最近接手的一个电…

2026/8/18 20:38:09 阅读更多 →

日新闻

告别逐帧截图:用 extract-video-ppt 快速提取视频中的 PPT 并一键导出 PDF

告别逐帧截图:用 extract-video-ppt 快速提取视频中的 PPT 并一键导出 PDF

告别逐帧截图:用 extract-video-ppt 快速提取视频中的 PPT 并一键导出 PDF 【免费下载链接】extract-video-ppt extract the ppt in the video 项目地址: https://gitcode.com/gh_mirrors/ex/extract-video-ppt 如果你还停留在"看网课 不停暂停 截图 …

2026/8/18 0:00:57 阅读更多 →
思源宋体TTF一站式上手:7个字重免费商用,从下载到上线的完整走查

思源宋体TTF一站式上手:7个字重免费商用,从下载到上线的完整走查

思源宋体TTF一站式上手:7个字重免费商用,从下载到上线的完整走查 【免费下载链接】source-han-serif-ttf Source Han Serif TTF 项目地址: https://gitcode.com/gh_mirrors/so/source-han-serif-ttf 你是不是也经历过这种时刻:设计稿里…

2026/8/18 0:00:58 阅读更多 →
华硕笔记本控制权回收指南:GHelper 如何用一个 10MB 文件替代 Armoury Crate

华硕笔记本控制权回收指南:GHelper 如何用一个 10MB 文件替代 Armoury Crate

华硕笔记本控制权回收指南:GHelper 如何用一个 10MB 文件替代 Armoury Crate 【免费下载链接】g-helper Lightweight Armoury Crate alternative for Asus laptops with nearly the same functionality. Works with ROG Zephyrus, Flow, TUF, Strix, Scar, ProArt, …

2026/8/18 0:00:59 阅读更多 →

周新闻

基于阿里云与通义千问(Qwen)构建AI应用:从模型调用到生产部署的完整实践指南

基于阿里云与通义千问(Qwen)构建AI应用:从模型调用到生产部署的完整实践指南

如果你是一名开发者,最近可能已经感受到了AI大模型正在从“玩具”变成“生产力工具”的强烈信号。从代码补全到智能Agent,从本地部署到云端API,我们正处在一个技术栈快速重构的节点。然而,面对层出不穷的模型、框架和工具&#xf…

2026/8/18 9:15:35 阅读更多 →
工业通信系统底层逻辑:04 反射——高频能量撞墙之后会发生什么?

工业通信系统底层逻辑:04 反射——高频能量撞墙之后会发生什么?

第四篇:反射——高频能量撞墙之后会发生什么? —— 你以为信号已经过去了,其实它正在回来打你 老Q的现场笔记 第五季,我们正式进入工业神经系统层。这里不再是单个设备的战斗,而是整个工厂“经脉”层面的秩序之战。从这一篇开始,你将第一次看清:看似简单的信号传播,背…

2026/8/18 9:06:28 阅读更多 →
【文章复现】非线性值迭代自适应动态规划(ADP):离散时间非线性系统的策略迭代自适应动态规划算法研究附Matlab代码

【文章复现】非线性值迭代自适应动态规划(ADP):离散时间非线性系统的策略迭代自适应动态规划算法研究附Matlab代码

✅作者简介:热爱科研的Matlab仿真开发者,擅长毕业设计辅导、数学建模、数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。🍎 往期回顾关注个人主页:Matlab科研工作室👇 关注我领取海量matlab电子书和…

2026/8/18 9:04:56 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/17 18:54:37 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/17 18:55:16 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/17 18:55:55 阅读更多 →