在 Qt 中,Qt Widgets 和 Qt Quick (QML) 都是开发图形用户界面(GUI)的框架,但它们有不同的特点、适用场景和优缺点。理解它们之间的区别能够帮助你根据项目需求选择最适合的框架。
1、Qt Widgets
Qt Widgets 是传统的 GUI 框架,它通过 C++ 编写和管理界面元素,适用于经典的桌面应用程序。它使用的是基于事件驱动的编程模型,利用传统的控件(如按钮、文本框等)来构建 UI。
1.1、特点
-
面向对象的 C++ 编程:
- 使用 C++ 编写应用程序,UI 元素和逻辑紧密耦合。
- UI 控件(如按钮、标签、表格等)是通过 C++ 代码创建和管理的。
-
传统桌面应用风格:
- 更适合传统的桌面应用,如文档编辑器、桌面小工具等。
- 更适合传统的桌面应用,如文档编辑器、桌面小工具等。
-
UI 组件丰富:
- Qt Widgets 提供了大量的传统 UI 控件,例如窗口、按钮、标签、表格、文本框等,如下图。
- Qt Widgets 提供了大量的传统 UI 控件,例如窗口、按钮、标签、表格、文本框等,如下图。
-
跨平台支持:
- Qt Widgets 支持多个操作系统,如 Windows、Linux 和 macOS,确保应用能够跨平台运行。
-
界面更新方式:
- Qt Widgets 使用事件驱动方式更新界面,通常是基于回调和信号槽机制来处理 UI 更新,**
回调和信号槽机制
**的内容后面会进行讲解。
- Qt Widgets 使用事件驱动方式更新界面,通常是基于回调和信号槽机制来处理 UI 更新,**
1.2、适用场景
- 传统桌面应用程序:如文本编辑器、IDE、文件管理器等。
- 需要精确控制的 UI:当你需要细致控制界面布局、事件和逻辑时,Qt Widgets 非常适合。
- 性能要求较高的应用:对于不需要太多动画或流畅交互的桌面应用,Qt Widgets 可以提供较高的性能。
1.3、优缺点
-
优点:
- 控件和布局控制精确,可以灵活定制。
- 对于经典桌面应用程序开发较为稳定,历史悠久,文档和社区支持丰富。
-
缺点:
- 对于复杂和动态的 UI,开发和维护难度较大。
- 整体开发速度相对较慢,特别是对于需要很多交互动画的应用。
1.4、应用示例
示例 1:基础窗口 + 按钮
打开VS软件,创建Qt Empty Application工程项目,新mainTest.cpp,内容如下:
#include <QtWidgets/QApplication>
#include <QtWidgets/QWidget>
#include <QtWidgets/QPushButton>
int main(int argc, char* argv[])
{
QApplication app(argc, argv);
QWidget window;
//set window title name
window.setWindowTitle("Basic Qt Window");
//create button
QPushButton* btn = new QPushButton("Click me", &window);
btn->move(50, 50);
//set window size
window.resize(800, 800);
window.show();
return app.exec();
}
编译运行,结果如下:
示例 2:信号与槽(按钮点击)
打开VS软件,创建Qt Empty Application工程项目,新mainTest.cpp,内容如下:
#include <QtWidgets/QApplication>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QMessageBox>
int main(int argc, char* argv[])
{
QApplication app(argc, argv);
//create button
QPushButton button("Say Hello");
//connect button to slot,信号和槽
QObject::connect(&button, &QPushButton::clicked, []() {
QMessageBox::information(nullptr, "Hello", "Hello from Qt!");
});
//set button size
button.resize(150, 50);
button.show();
return app.exec();
}
编译运行,结果如下:(点击1后出现2中的内容)
示例 3:布局管理(竖直布局)
打开VS软件,创建Qt Empty Application工程项目,新mainTest.cpp,内容如下:
#include <QtWidgets/QApplication>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QMessageBox>
#include <QtWidgets/QVBoxLayout>
int main(int argc, char* argv[])
{
QApplication app(argc, argv);
//create window
QWidget window;
//create layout 创建个竖直布局按钮
QVBoxLayout* layout = new QVBoxLayout(&window);
layout->addWidget(new QPushButton("Button 1"));
layout->addWidget(new QPushButton("Button 2"));
layout->addWidget(new QPushButton("Button 3"));
window.setLayout(layout);
//set window title
window.setWindowTitle("Layout Example");
window.show();
return app.exec();
}
编译运行,结果如下:
示例 4:表单界面(QLabel + QLineEdit)
打开VS软件,创建Qt Empty Application工程项目,新mainTest.cpp,内容如下:
#include <QtWidgets/QApplication>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QMessageBox>
#include <QtWidgets/QVBoxLayout>
#include <QtWidgets/QFormLayout>
#include <QtWidgets/QLineEdit>
int main(int argc, char* argv[])
{
QApplication app(argc, argv);
QWidget window;
//create layout
QFormLayout* formLayout = new QFormLayout;
//create controls
QLineEdit* nameEdit = new QLineEdit;
QLineEdit* emailEdit = new QLineEdit;
//add controls
formLayout->addRow("Name:", nameEdit);
formLayout->addRow("Email:", emailEdit);
formLayout->addRow(new QPushButton("Submit"));
//set window
window.setLayout(formLayout);
window.setWindowTitle("Form Example");
window.show();
return app.exec();
}
编译运行,结果如下:
示例 5:QTimer + 动态更新界面
打开VS软件,创建Qt Empty Application工程项目,新mainTest.cpp,内容如下:
#include <QtWidgets/QApplication>
#include <QtWidgets/QLabel>
#include <QtCore/QTimer>
int main(int argc, char* argv[])
{
QApplication app(argc, argv);
//create label
QLabel label("0");
label.resize(200, 200);
//set font size
label.setFont(QFont("Arial", 50));
label.show();
int counter = 0;
//create timer
QTimer* timer = new QTimer;
//connect timer to label update
QObject::connect(timer, &QTimer::timeout, [&]() {
label.setText(QString::number(++counter));
});
//start timer
timer->start(1000); // 每秒更新一次
return app.exec();
}
编译运行,结果如下:
Qt Widgets的相关例子就展示到这里,相关的应用会在Qt+PCL的软件涉及到,喜欢的可以关注订阅。
2、Qt Quick (QML)
Qt Quick 是 Qt 提供的一种更现代的 GUI 开发框架,基于 QML(Qt Modeling Language)语言,结合了声明式编程和 JavaScript。QML 提供了更丰富的动画效果、更灵活的布局管理,使得创建动态和现代化的用户界面变得更加容易。
2.1、特点
-
声明式 UI 和 JavaScript 脚本:
- 使用 QML 编写 UI,UI 元素以声明式方式描述,逻辑部分可以通过 JavaScript 编写。
- QML 的语法简单易懂,适合快速开发和原型设计。
-
现代化的 UI 设计:
- Qt Quick 提供了丰富的动画和过渡效果,适用于现代化、流畅的界面设计。
- 很适合开发具有动态效果、动画和多点触控支持的应用。
-
与 C++ 集成:
- 尽管 QML 使用 JavaScript 描述 UI,但 Qt Quick 允许与 C++ 后端进行集成,C++ 可以处理逻辑、数据处理等。
-
跨平台支持:
- Qt Quick 也支持多个平台,包括桌面、移动设备、嵌入式设备等,可以轻松创建跨平台的应用。
-
性能:
- Qt Quick 使用 OpenGL(或 Vulkan)作为渲染引擎,提供高效的图形渲染。适合高效的图形处理,尤其是在移动设备或需要流畅动画的场合。
2.2、适用场景
- 现代化应用:如移动应用、现代化桌面应用、需要丰富动画和动态效果的应用。
- 多平台应用:如同一个应用需要在桌面、手机或嵌入式设备上运行。
- 快速开发:如果项目需求是快速原型或迭代开发,QML 提供了高效的开发体验。
2.3、优缺点
-
优点:
- 更简洁的声明式语法,快速开发和原型设计。
- 丰富的动画和动态效果,适合现代化的用户体验设计。
- 可以跨平台开发,支持桌面和移动设备。
-
缺点:
- 性能上相比于 Qt Widgets 可能稍逊一筹,特别是对于需要高性能处理的应用。
- 调试和测试可能较为复杂,尤其是在 JavaScript 和 C++ 的集成上。
- 对于非常复杂的界面布局或逻辑,QML 的表现可能不如 Qt Widgets 那样稳定。
2.4、应用示例
示例
打开VS软件,创建Qt Empty Application工程项目,新main.cpp,内容如下:
#include <QtGui/QGuiApplication>
#include <QtQml/QQmlApplicationEngine>
#include <QtQml/QQmlContext>
#include "backend.h"
int main(int argc, char* argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
Backend backend;
engine.rootContext()->setContextProperty("Backend", &backend);
const QUrl url("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();
}
backend.h
文件的内容如下:
#pragma once
#include <QObject>
class Backend : public QObject {
Q_OBJECT
public:
explicit Backend(QObject* parent = nullptr) {}
Q_INVOKABLE QString getInfo() const {
return "Hello,Common from C++ Chapter";
}
Q_INVOKABLE void onButtonClicked() {
qDebug("button C++ clicked");
}
};
main.qml
的内容如下:
/*
import QtQuick 2.3
Rectangle {
width: 200
height: 100
color: "red"
Text {
anchors.centerIn: parent
text: "Hello, World!"
}
}
*/
import QtQuick 2.15
import QtQuick.Controls 2.15
ApplicationWindow {
visible: true
width: 400
height: 300
title: qsTr("Qt Quick + C++ Example")
Column {
anchors.centerIn: parent
spacing: 20
Text {
id: output
text: Backend.getInfo()
font.pixelSize: 20
}
Button {
text: "click C++ function"
onClicked: Backend.onButtonClicked()
}
}
}
qml.qrc的内容如下:
<RCC>
<qresource prefix="/">
<file>main.qml</file>
</qresource>
</RCC>
运行结果如下:
3、Qt Widgets 与 Qt Quick(QML)的选择
在选择 Qt Widgets 或 Qt Quick 时,考虑以下因素可以帮助你做出决策:
1. 项目的复杂度与需求
- 如果你需要精细的控件管理,尤其是传统桌面应用程序,Qt Widgets 可能是更好的选择。
- 如果你需要实现动态和现代化的用户界面,特别是涉及动画、过渡和触摸操作时,Qt Quick 更加适合。
2. 开发速度与原型设计
- Qt Quick (QML) 更加适合快速开发和原型设计。声明式的 UI 和 JavaScript 脚本可以更快地迭代和调整界面。
- Qt Widgets 在开发时可能需要更多的代码和手动处理事件,但它对于复杂和精确的 UI 控件布局有更高的控制。
3. 性能要求
- 如果你的应用需要处理大量数据或图形,Qt Widgets 通常提供更好的性能,因为它直接操作底层图形库。
- 对于需要丰富动画和过渡效果的应用,Qt Quick 在性能和视觉效果方面表现优异,尤其是在现代硬件上。
4. 平台支持
- 如果你的应用需要在桌面和移动设备上运行,或者你考虑将应用移植到嵌入式平台,Qt Quick 是更好的选择。
- Qt Widgets 更适合传统的桌面应用,特别是没有太多动态效果的应用。
5. 开发人员的技能
- 如果你的开发团队熟悉 C++ 和传统桌面应用程序开发,Qt Widgets 可能更易上手。
- 如果开发团队希望快速创建现代化界面并且有 JavaScript 开发经验,Qt Quick 将更具吸引力。
4、总结
- Qt Widgets:适合传统的桌面应用,提供精确的控件和布局管理,但在现代化动态界面和跨平台支持方面不如 Qt Quick 强大。
- Qt Quick (QML):适合现代化的动态界面,支持快速开发和跨平台部署,尤其是在移动设备和嵌入式设备上有优势,但在性能上可能稍逊一筹。
根据你的项目需求、开发经验和目标平台选择最合适的框架。如果你的应用需要大量动态界面、动画效果、以及跨平台支持,选择 Qt Quick 会更合适;如果你需要更传统、复杂的桌面应用,则选择 Qt Widgets。由于Qt+PCL中没有动态效果,为桌面应用程序开发,所以笨教材选择Qt Widgets。
至此完成第五讲的内容,欢迎喜欢朋友的关注订阅!