Skip to content

Qt Overview

UI模块化架构

Qt C++ 有许多好的UI模块化的架构,以下是其中一些:

  1. Model-View-Controller (MVC):这是一种经典的设计模式,用于将应用程序的用户界面、数据和逻辑分离开来。在Qt中,您可以使用QAbstractItemModel类来创建您的数据模型,并使用QWidgetQML视图来显示它。

  2. Model-View-ViewModel (MVVM):这是另一种常见的UI架构,其中视图与底层数据和逻辑分离。在Qt中,您可以使用QQmlApplicationEngine类来创建QML界面,并使用QObject派生类作为视图模型。

  3. Flux:这是一个由Facebook提出的UI架构,旨在简化应用程序状态管理。在Qt中,您可以使用QStateQStateMachine类来管理应用程序状态,并使用信号和槽机制传递事件。

  4. Reactive Programming:这是一种响应式编程范例,旨在处理异步数据流。在Qt中,您可以使用RxCpp库来实现反应式编程,并结合其他UI架构进行开发。

  5. Component-based UI:这是一种基于组件的UI设计方法,在不同的应用程序之间重复使用可重复利用的组件。在Qt中,您可以通过自定义QWidgetQML元素并将其封装到单独的库中来实现此目标。

插件化系统架构

Qt提供了强大的插件系统,其IDE - Qt Creator就是很好的插件化系统架构示例。

我的Qt Plugin Test Repo

Pimpl idiom

Pimpl idiom - Pointer to Implementation(也称为编译器防火墙)是一种C++编程惯用法,用于隐藏类的实现细节并减少编译时间。它通过将类的实现细节封装在一个单独的类中,并通过指针将其与公共接口类分离来实现。

在Qt中,许多类都是用了这种模式。其中经典的例子是namespace Ui

// DeviceDialog.h

#ifndef DEVICEDIALOG_H
#define DEVICEDIALOG_H

#include <QDialog>

namespace Ui {
class DeviceDialog;
}

class DeviceDialog : public QDialog
{
    Q_OBJECT

private:
    Ui::DeviceDialog *ui;
};

#endif // DEVICEDIALOG_H
<!-- DeviceDialog.ui -->
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
    <class>DeviceDialog</class>
    <widget class="QDialog" name="DeviceDialog">
        <widget class="QPushButton" name="btnMicClose">
            <property name="geometry">
                <rect>
                <x>130</x>
                <y>40</y>
                <width>111</width>
                <height>31</height>
                </rect>
            </property>
            <property name="text">
                <string>Mic Close</string>
            </property>
        </widget>
    </widget>
    <resources/>
    <connections/>
</ui>
// DeviceDialog.cpp
#include "devicedialog.h"
#include "ui_devicedialog.h"

DeviceDialog::DeviceDialog(QWidget *parent) :
    QDialog(parent), ui(new Ui::DeviceDialog)
{
    ui->setupUi(this);

    // ui operations ...
    ui->txtLog->document()->setMaximumBlockCount(300);

}
// main.cpp
#include <QApplication>
#include "devicedialog.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    DeviceDialog w;
    w.show();
    return a.exec();
}

这样每次修改GUI文件(*.ui)时,只会重新生成ui_devicedialog.h,只影响本ui模块的cpp文件DeviceDialog.cpp,只有它需要重新编译。

不会影响devicedialog.h,也不会影响包含devicedialog.h的其他模块(比如,上述的main.cpp),这些其他模块不需要重新编译。

避免了修改GUI导致的链式重新编译问题。

综合来说,这样的好处有:

  1. 最小化编译依赖项 - 减少编译时间
  2. 接口与实现的分离
  3. 可移植性 - 二进制兼容性

Pimpl

当impl类发生变化时,接口类自身的内存布局不会被影响,接口类的客户端也不会受影响。 特别适合制作库。

Qt Creator主题

  1. Dracula - A dark theme for Qt Creator

  2. Monokai color theme

第三方UI库

  1. Telegram's UI library which adds "modern" style to Qt Widgets
  2. Qt Material Widgets
  3. Qt-Material QSS
  4. QSkinny
  5. 花里胡哨控件集合 Qt-ShowyWidgets
  6. 付费QFluentWidgets
  7. ElaWidgetTools
  8. zhuzichu520 FluentUI
  9. zhuzichu520 FluentUI Pro

我的Qt项目

  1. BLE Tool

官方参考

  1. Qt Project Git Repository Browser
  2. Qt Creator Git Repository Browser
  3. QML 和 的最佳实践Qt Quick
  4. Qt Design Studio
  5. Qt Framework preview - Vehicle HMI System
  6. KDAB CEO推荐:Qt开发、调试、诊断的十大工具