当前位置: 首页 > news >正文

QML与C++交互的方式

QML(Qt Meta Language 或 Qt Modeling Language)是 Qt 框架中用于描述用户界面的声明式语言,它非常适合用来构建流畅、动态的应用程序界面。C++ 则常被用来实现应用程序的核心逻辑和性能关键部分。为了充分利用两者的优势,Qt 提供了多种方式让 QML 和 C++ 之间进行交互。
1, 使用 Q_INVOKABLE 关键字
通过在 C++ 类中使用 Q_INVOKABLE 关键字,可以使得该方法能够直接从 QML 中调用。首先,你需要确保这个类继承自 QObject 并且使用了 Q_OBJECT 宏。

#pragma once#include <QObject>class MyWidget : public QObject
{Q_OBJECTpublic:MyWidget(QObject*parent = nullptr);~MyWidget();Q_INVOKABLE QString myInvokableMethod(const QString& input) {return "Hello, ccccc" + input;}
};
#include "MyWidget.h"MyWidget::MyWidget(QObject*parent): QObject(parent)
{}MyWidget::~MyWidget()
{}

Main函数中

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "MyWidget.h"
#include <QQmlContext>
int main(int argc, char *argv[])
{
#if defined(Q_OS_WIN) && QT_VERSION_CHECK(5, 6, 0) <= QT_VERSION && QT_VERSION < QT_VERSION_CHECK(6, 0, 0)QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endifQGuiApplication app(argc, argv);QQmlApplicationEngine engine;MyWidget myObject;engine.rootContext()->setContextProperty("myCppObject", &myObject); // 设置上下文属性//qmlRegisterType<MyWidget>("com.example.myclass", 1, 0, "MyWidget"); // 注册类型engine.load(QUrl(QStringLiteral("qrc:/qt/qml/qtquickapplicationtest01/main.qml")));if (engine.rootObjects().isEmpty())return -1;return app.exec();
}

qml调用

import QtQuick 2.9
import QtQuick.Window 2.2
//import com.example.myclass 1.0 // 导入我们注册的模块
Window {visible: truewidth: 640height: 480title: "QtQuickApplicationTest01"//MyWidget { id: myCppObject } // 创建C++类的实例Text {anchors.fill: parenthorizontalAlignment: Text.AlignHCenterverticalAlignment: Text.AlignVCenterfont.bold: truefont.pointSize: 42text: "Hello World!"MouseArea {anchors.fill: parentonClicked: {console.log(myCppObject.myInvokableMethod("World")) // 调用可调用方法}}}}

该方法只在main中创建一次,不适用多次
2,注册方式
main函数中

 qmlRegisterType<MyWidget>("com.example.myclass", 1, 0, "MyWidget"); // 注册类型

调用过程

import QtQuick 2.9
import QtQuick.Window 2.2
import com.example.myclass 1.0 // 导入我们注册的模块
Window {visible: truewidth: 640height: 480title: "QtQuickApplicationTest01"MyWidget { id: myCppObject } // 创建C++类的实例Text {anchors.fill: parenthorizontalAlignment: Text.AlignHCenterverticalAlignment: Text.AlignVCenterfont.bold: truefont.pointSize: 42text: "Hello World!"MouseArea {anchors.fill: parentonClicked: {console.log(myCppObject.myInvokableMethod("World")) // 调用可调用方法}}}}

该方法可以创建多个实例
3,使用是 Qt 的宏 Q_PROPERTY,它的作用是:将 C++ 类中的一个属性暴露给 Qt 的元对象系统(Meta-Object System),从而可以在 QML 中直接访问和绑定这个属性。
如下代码

#pragma once#include <QObject>class MyWidget : public QObject
{Q_OBJECTpublic:MyWidget(QObject*parent = nullptr);~MyWidget();Q_PROPERTY(QString message READ message WRITE setMessage NOTIFY messageChanged)Q_INVOKABLE QString myInvokableMethod(const QString& input) {return "Hello, ccccc" + input;}QString message() const;void setMessage(const QString& message);signals:void messageChanged();private:QString m_message;};
#include "MyWidget.h"
#include <qDebug>
MyWidget::MyWidget(QObject*parent): QObject(parent)
{}MyWidget::~MyWidget()
{}QString MyWidget::message() const
{return m_message;
}void MyWidget::setMessage(const QString& message)
{if (m_message != message) {m_message = message;emit messageChanged();qDebug() << "Signal emitted:";}
}
import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 2
import com.example.myclass 1.0 // 导入我们注册的模块
Window {visible: truewidth: 640height: 480title: "QtQuickApplicationTest01"MyWidget {id: myCppObject/*onMessageChanged: {console.log("Direct connection: message changed!")parent.text = "Received: " + myCppObject.message}*/} Connections {target: myCppObjectonMessageChanged: {console.log("1234")}}Column{spacing:30Text {font.bold: truefont.pointSize: 42text: "Hello World!"MouseArea {anchors.fill: parentonClicked: {myCppObject.message = "Hello from QML!"}}}Label {id: labeltext:"change message"font.pointSize: 42MouseArea {anchors.fill: parentonClicked: {label.text= myCppObject.message}}}}}
http://www.lryc.cn/news/612887.html

相关文章:

  • Kafka数据生产和发送
  • 基于Spring Cloud Stream与Kafka的事件驱动微服务架构设计与实战指南
  • 【Kafka系列】第二篇| Kafka 的核心概念、架构设计、底层原理
  • MQTT:Dashboard访问授权
  • MQTT:Dashboard黑名单与连接抖动
  • 【LeetCode】set和map相关算法题 前K个高频单词、随机链表的复制、两个数组的交集、环形链表
  • Flink-1.19.0源码详解9-ExecutionGraph生成-后篇
  • VScode使用jupyter notebook,配置内核报错没有torch解决
  • 贪心算法分析与解决指南
  • 1.电动汽车动力电池系统技术介绍与分类
  • 机器视觉系统工业相机的成像原理及如何选型
  • OpenCV图像处理入门实战指南
  • 为什么需要日志收集系统
  • 【运维】自动化生产环境部署工作流
  • Mac/Windows跨平台PDF与AI高效解决方案
  • day 48 模型的可视化与推理
  • 连续最高天数的销售额(动态规划)
  • 3D 软件在游戏开发中的全链路应用:从原型到上线的实战解析
  • 音乐创作好助手—— 蘑兔音乐
  • 【自动驾驶】《Sparse4Dv3》代码学习笔记
  • uniapp/uniappx实现图片或视频文件选择时同步告知权限申请目的解决华为等应用市场上架审核问题
  • 行业应用案例:MCP在不同垂直领域的落地实践
  • 学深度学习,有什么好的建议或推荐的书籍?
  • 深入解析Java类加载机制:双亲委派模型的设计与实现
  • 开源大模型实战:GPT-OSS本地部署与全面测评
  • Android 之 Jetpack - Lifecycle
  • 告别复杂配置!cpolar让Prometheus监控突破网络限制
  • 【PHP 接口(Interface)完全入门指南】
  • 力控汽车零部件冲压MES系统方案
  • 汽车线束设计—导线的选取