【Q&A】组合模式在Qt有哪些应用?

在Qt框架里,组合模式的设计应用较为广泛,以下是一些具体的例子:

1. QObject 及其派生类体系

QObject 是Qt中绝大多数类的基类,它构建了一个树形的对象结构,这和组合模式的理念相契合。每个 QObject 对象都可以有父对象和子对象,借助 setParent() 方法能够构建对象树。当父对象被销毁时,其所有子对象也会被自动销毁。

cpp 复制代码
#include <QApplication>
#include <QWidget>
#include <QLabel>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    // 创建一个父窗口
    QWidget *parentWidget = new QWidget();
    parentWidget->setWindowTitle("Parent Widget");

    // 创建一个子标签,将父窗口作为其父对象
    QLabel *childLabel = new QLabel("This is a child label", parentWidget);

    parentWidget->show();

    return a.exec();
}

在这个例子中,QWidget 作为父对象,QLabel 作为子对象。当 parentWidget 被销毁时,childLabel 也会自动被销毁。

2. QGraphicsItem 及其派生类

在Qt的图形视图框架中,QGraphicsItem 是所有图形项的基类,它支持组合模式。图形项可以包含子图形项,从而构建出复杂的图形场景。

cpp 复制代码
#include <QApplication>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsRectItem>
#include <QGraphicsEllipseItem>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    // 创建场景
    QGraphicsScene scene;

    // 创建一个矩形图形项作为父项
    QGraphicsRectItem *parentRect = new QGraphicsRectItem(0, 0, 100, 100);
    scene.addItem(parentRect);

    // 创建一个椭圆图形项作为子项
    QGraphicsEllipseItem *childEllipse = new QGraphicsEllipseItem(20, 20, 50, 50, parentRect);

    // 创建视图并显示场景
    QGraphicsView view(&scene);
    view.show();

    return a.exec();
}

在这个例子中,QGraphicsRectItem 是父图形项,QGraphicsEllipseItem 是子图形项。子图形项的位置和变换是相对于父图形项的。

3. QMenuQAction

QMenu 类用于创建菜单,QAction 类用于表示菜单项。一个 QMenu 可以包含多个 QAction,还可以包含子菜单,这形成了一个树形结构。

cpp 复制代码
#include <QApplication>
#include <QMainWindow>
#include <QMenuBar>
#include <QMenu>
#include <QAction>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QMainWindow window;

    // 创建菜单栏
    QMenuBar *menuBar = window.menuBar();

    // 创建主菜单
    QMenu *fileMenu = menuBar->addMenu("File");

    // 创建菜单项
    QAction *openAction = new QAction("Open", &window);
    QAction *saveAction = new QAction("Save", &window);

    // 将菜单项添加到主菜单
    fileMenu->addAction(openAction);
    fileMenu->addAction(saveAction);

    // 创建子菜单
    QMenu *importMenu = fileMenu->addMenu("Import");
    QAction *importTextAction = new QAction("Import Text", &window);
    importMenu->addAction(importTextAction);

    window.show();

    return a.exec();
}

在这个例子中,QMenuBar 是根,QMenu 是树枝节点,QAction 是叶子节点。通过这种方式,可以构建出复杂的菜单系统。

4. QTreeWidgetQTreeWidgetItem

QTreeWidget 是一个用于显示树形结构数据的控件,QTreeWidgetItem 表示树中的项。可以通过 addChild() 方法将一个 QTreeWidgetItem 添加到另一个 QTreeWidgetItem 作为子项,从而构建树形结构。

cpp 复制代码
#include <QApplication>
#include <QTreeWidget>
#include <QTreeWidgetItem>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QTreeWidget treeWidget;
    treeWidget.setColumnCount(1);

    // 创建根项
    QTreeWidgetItem *rootItem = new QTreeWidgetItem(&treeWidget);
    rootItem->setText(0, "Root");

    // 创建子项
    QTreeWidgetItem *childItem1 = new QTreeWidgetItem(rootItem);
    childItem1->setText(0, "Child 1");

    QTreeWidgetItem *childItem2 = new QTreeWidgetItem(rootItem);
    childItem2->setText(0, "Child 2");

    treeWidget.show();

    return a.exec();
}

在这个例子中,QTreeWidget 是容器,QTreeWidgetItem 构成了树形结构,根项可以有多个子项,子项也可以有自己的子项。

5. QFileInfo 与 QDir 类

QFileInfo 类用于获取文件或目录的信息,而 QDir 类用于操作目录及其内容。QDir 可以包含多个文件和子目录,这类似于组合模式中的树枝节点,而文件则类似于叶子节点。

cpp 复制代码
#include <QCoreApplication>
#include <QDir>
#include <QFileInfo>
#include <QDebug>

// 递归遍历目录
void traverseDirectory(const QDir &dir, int level = 0) {
    QString indent(level * 4, ' ');
    QFileInfoList entries = dir.entryInfoList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot);
    for (const QFileInfo &entry : entries) {
        if (entry.isDir()) {
            qDebug() << indent + "+ " + entry.fileName();
            traverseDirectory(QDir(entry.absoluteFilePath()), level + 1);
        } else {
            qDebug() << indent + "- " + entry.fileName();
        }
    }
}

int main(int argc, char *argv[]) {
    QCoreApplication a(argc, argv);

    QDir rootDir("your_directory_path");
    if (rootDir.exists()) {
        traverseDirectory(rootDir);
    }

    return a.exec();
}

在上述代码中,traverseDirectory 函数递归地遍历指定目录及其子目录。QDir 就像树枝节点,它可以包含多个文件(叶子节点)和子目录(新的树枝节点)。

相关推荐
努力努力再努力wz11 小时前
【Qt入门系列】:QLabel控件详解:从文本显示到图片展示,再到内容布局与伙伴机制
android·开发语言·数据结构·数据库·c++·qt·mysql
郝学胜-神的一滴13 小时前
Qt 高级开发 016:半内存管理机制
开发语言·c++·qt·程序人生·用户界面
香菇滑稽之谈13 小时前
VSCode配置QT环境
ide·vscode·qt
雪的季节13 小时前
Qt pro 多项目、子目录、多层级配置(超级详细 + 实战模板)
qt
郝学胜-神的一滴13 小时前
Qt 高级开发 020:水平布局手写代码实战
开发语言·c++·qt·系统架构·软件构建·用户界面
机器视觉知识推荐、就业指导1 天前
Qt6 + QCustomPlot 实时曲线 Demo ,适合串口与上位机项目
qt
workflower1 天前
具身智能研究对象:物理交互中的智能行为
设计模式·动态规划·软件工程·软件构建·scrum
YY&DS1 天前
Qt 嵌入 CEF 在 Linux 下必须设置 `QT_XCB_GL_INTEGRATION=xcb_egl才能加载网页
linux·开发语言·qt
秋田君1 天前
Qt 5.12.8 下载与安装教程(附网盘资源)
开发语言·qt
折哥的程序人生 · 物流技术专研1 天前
Java 23 种设计模式:从踩坑到精通 | 抽象工厂 —— 支付/收款如何成套创建?跨平台 UI 如何一键换肤?
java·开发语言·后端·设计模式