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

Qt QML and Qt Quick 简述及例程

Qt QML and Qt Quick 简述及例程

  • 引言
  • 一、简述
    • 1.1 QML简述
    • 1.2 Qt Quick简述
  • 二、例程
    • 2.1 新建Qt Quick应用
    • 2.2 qml与c++ 实现信号和槽的数据传输
    • 2.3 测试cpp中信号参数不为QVariant的情况,传输是否正常
  • 三、参考链接

引言

QML是一种声明式语言,专门用于设计用户界面,而Qt Quick是基于QML的框架,用于构建现代、动态的UI。QML采用简洁的声明式语法,允许开发者通过类似JSON的结构快速定义UI组件和交互逻辑。与传统的命令式编程(如C++)相比,代码量更少,可读性更强,适合快速迭代和原型设计。Qt Quick支持Windows、macOS、Linux、Android和iOS等平台,通过一次编写即可部署到多个系统,减少平台适配成本。其渲染引擎(如Scene Graph)优化了性能,确保在不同设备上流畅运行。

一、简述

1.1 QML简述

  • QML(Qt Meta-Object Language)是一种声明式脚本语言,用于描述应用程序的用户界面。它基于 JavaScript 语法,允许开发者通过简洁的代码定义界面元素及其交互逻辑。QML 的核心优势在于其可读性和高效性,适合快速构建动态、响应式的 UI。
  • 1. 核心特性

声明式语法:通过类似 JSON 的语法定义界面元素,代码简洁易读。
数据绑定:支持属性绑定机制,自动同步数据与 UI 的变化。
JavaScript 集成:可直接嵌入 JavaScript 处理逻辑,增强交互能力。
跨平台支持:基于 Qt 框架,可部署到桌面、移动和嵌入式系统。
组件化设计:支持自定义可复用组件,提升开发效率。

  • 2. qml与c++交互

绑定属性:通过 Q_PROPERTY 定义可绑定属性,QML 可自动同步数据变化。
信号与槽:QML 可直接调用 C++ 的信号和槽函数。
注册QML:通过 qmlRegisterType 将 C++ 类注册为 QML 类型,允许在 QML 中实例化。
上下文属性:通过 QQmlContext 将 C++ 对象或数据暴露给 QML。在 C++ 中注册对象后,QML 可直接访问其属性和方法。

1.2 Qt Quick简述

  • Qt Quick 是 QML 的配套框架,提供了一系列预定义的 QML 类型(如矩形、文本、动画等)和模块(如 QtQuick.Controls 用于控件)。它利用硬件加速的图形渲染引擎(Scene Graph),能够高效处理复杂动画和视觉效果。
  • 1. 核心特性

跨平台:支持 Windows、macOS、Linux、Android 和 iOS。
硬件加速:基于不同的操作系统,灵活利用 OpenGL 或 Vulkan 实现高性能渲染。
数据绑定:通过属性绑定自动更新 UI。
C++ 集成:可将 QML 与 C++ 逻辑结合,提升性能。

  • 2. 主要库

QtQuick 模块:提供基础的 QML 类型 (如 Item、Rectangle),包含场景图渲染引擎,优化性能
QtQuick.Controls:提供标准化 UI 控件 (如按钮、滑块、对话框),支持多种样式 (如 Material、Fusion)
QtQuick.Layouts:动态布局管理(如 RowLayout、GridLayout)
QtQuick.Dialogs:预置对话框(文件选择、颜色选择等)
QtQuick.Shapes:高级矢量图形绘制(路径、贝塞尔曲线)
QtQuick.Particles:粒子系统(用于特效如火焰、烟雾)

二、例程

2.1 新建Qt Quick应用

  • 需注意:新建Qt Quick应用时,minimum required QT version默认选的版本可能并没有安装, (无脑下一步可能会显示:No suitable kits found.),需选择已安装的编译器版本。
    1. 和创建Qt窗体或控制台程序一样,可无脑下一步,结果如下所示: 在这里插入图片描述
    1. main.cpp中加载了qml文件,具体的显示部分在main.qml中实现,也可在cpp文件中获取其界面上的对象进行修改,如代码所示:
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQuickWindow>int main(int argc, char *argv[])
{QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);QGuiApplication app(argc, argv);QQmlApplicationEngine engine;engine.load(QUrl(QStringLiteral("qrc:/main.qml")));if (engine.rootObjects().isEmpty())return -1;QObject *rootObject = engine.rootObjects().first();QQuickWindow *window = qobject_cast<QQuickWindow *>(rootObject);if (window) {window->setWidth(480);}return app.exec();
}

2.2 qml与c++ 实现信号和槽的数据传输

  • 结果如下:
    在这里插入图片描述
  • main.qml源码:
import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 2.2
import com.example 1.0Window {visible: truewidth: 640height: 480title: qsTr("Hello World")Backend {id: backendonSendInt: console.log("Received int from C++:", value)}Button {text: "Send Int to C++"onClicked: backend.receiveInt(1) // 发送int到C++}Button {y: 50text: "Trigger C++ Signal"onClicked: backend.sendInt(2)  // 触发C++信号}
}
  • main.cpp源码:
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQuickWindow>
#include <QQmlContext>class Backend : public QObject {Q_OBJECT
public:explicit Backend(QObject *parent = nullptr) : QObject(parent) {}
public slots:void receiveInt(int value) {qDebug() << "Received int from QML:" << value;}
signals:void sendInt(int value);
};int main(int argc, char *argv[])
{QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);QGuiApplication app(argc, argv);qmlRegisterType<Backend>("com.example", 1, 0, "Backend");QQmlApplicationEngine engine;Backend backend;engine.rootContext()->setContextProperty("backend", &backend);engine.load(QUrl(QStringLiteral("qrc:/main.qml")));if (engine.rootObjects().isEmpty())return -1;return app.exec();
}#include "main.moc"

2.3 测试cpp中信号参数不为QVariant的情况,传输是否正常

  • minimum required QT version选的是5.9,上述代码中参数是int,传输正常。在qml改用function,而不是用onSendInt (注:改用function,在cpp中connect信号与function后与onSendInt可能有冲突,需删掉qml中的onSendInt,源码在后面)。
  • 使用QVariant 和 使用QString结果如下,使用QString连接信号槽会报错,qml里function的参数应该默认就是QVariant

函数语句是js语句,是不能指定类型,只能使用QVariant

在这里插入图片描述


在这里插入图片描述

  • main.cpp中源码如下:
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQuickWindow>
#include <QQmlContext>class Backend : public QObject {Q_OBJECT
public:explicit Backend(QObject *parent = nullptr) : QObject(parent) {}
public slots:void receiveInt(QString value) {qDebug() << "Received int from QML:" << value;emit sendInt(value);}
signals:void sendInt(QString value);
};int main(int argc, char *argv[])
{QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);QGuiApplication app(argc, argv);qmlRegisterType<Backend>("com.example", 1, 0, "Backend");QQmlApplicationEngine engine;Backend backend;engine.rootContext()->setContextProperty("backend", &backend);engine.load(QUrl(QStringLiteral("qrc:/main.qml")));if (engine.rootObjects().isEmpty())return -1;QObject *rootObject = engine.rootObjects().first();QObject::connect(&backend, SIGNAL(sendInt(QString)), rootObject, SLOT(onTest(QString)));return app.exec();
}#include "main.moc"
  • main.qml中源码如下:
import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 2.2
import com.example 1.0Window {visible: truewidth: 640height: 480title: qsTr("Hello World")function onTest(str) {console.log("onTest from C++:", str)}Button {text: "Send Int to C++"onClicked: backend.receiveInt("111") // 发送int到C++}}

三、参考链接

  • QT6中绘制UI的两种技术详解与示例展示:https://blog.csdn.net/XiaoWang_csdn/article/details/148040458
  • QML与C++混合编程详解:https://blog.csdn.net/iEearth/article/details/42243553
  • QtQuick 系列教程之 QML 与 C++ 交互:https://cloud.tencent.com/developer/article/1169582
  • C++ 与 QML 之间进行数据交互的几种方法:https://www.cnblogs.com/jzcn/p/17774676.html
  • QML和C++信号与槽:https://blog.csdn.net/Path_of_programm/article/details/146600889
  • 简单谈谈为什么QML和CPP的信号链接参数数据类型要使用QVariant:https://blog.csdn.net/manyoudian/article/details/141404951
http://www.dtcms.com/a/395778.html

相关文章:

  • Linux 系统移植
  • 小杰机器学习(six)——概率论——1.均匀分布2.正态分布3.数学期望4.方差5.标准差6.多维随机变量及其分布
  • 【Linux】Ext系列文件系统(上)
  • 【ROS2】Beginner: Client libraries - 发布者、订阅者例子 C++ Python
  • AI设计功能性病毒:从DNA语言模型到精准杀菌实战
  • Qt 共享指针QSharedPointer与std::shared_ptr
  • Java课程 第02周 预习、实验与作业:Java基础语法2:面向对象入门
  • 词性标注技术漫谈:为词语赋予语法灵魂的旅程
  • K230基础-MicroPython
  • 网站访问问题:无法访问此网站、404
  • Redis 与Memcached 的对比
  • PyTorch 神经网络工具箱:核心原理与实践指南
  • 广义矩估计错误指定时的一个推导【续5】
  • 【STM32】ADC数模转换器
  • Tensorboard学习记录
  • Redis中常见数据结构底层实现结构是什么
  • 高频交易技术演进:从毫秒到纳秒的极限延迟优化之路
  • 从零开始搭建并部署一个基于Django和YOLO的智能模型项目
  • MySQL零基础学习Day2——数据库基础操作
  • 数学笔试选择题:题组1
  • Linux常用命令51——tail查看文件尾部内容
  • Django多数据库配置:mysql、mongo、redis、达梦
  • 图像拼接(反向拼接巨难,求指教!)
  • [免费]基于Python的深度学习音乐推荐系统(后端Django)【论文+源码+SQL脚本】
  • 南华 NHL-1 型加载减速工况法轻型柴油车烟度检测系统:技术解析与实战指南
  • 学习Java遇到的一些问题
  • 基于SpringBoot招聘信息管理系统
  • 多线程—线程通信之notifyAll()/wait()方法Demo
  • kotlin 常用函数
  • 2025年CSP-J1入门级初赛题解