Qt:多文档模式开发
多文档
- 一、`QMdiArea` (多文档界面)
- 1.1 使用步骤
- 1.2 特点
- 二、 `QTabWidget` (标签页界面)
- 2.1 使用步骤
- 2.2 特点
- 2.3 如何选择
在 Qt 中,在主窗口中生成并管理多个处理窗口(子窗口)是一个非常常见的需求。Qt 提供了两种主流的解决方案:QMdiArea
(多文档界面) 和 QTabWidget
(标签页界面)。
一、QMdiArea
(多文档界面)
QMdiArea
是专门为创建“多文档界面”(Multiple Document Interface, MDI)而设计的控件。它允许你在主窗口内部创建多个浮动或平铺的子窗口,就像经典的 Visual Studio 或 Photoshop 那样。
QMdiArea
:作为子窗口的容器。QMdiSubWindow
:每个子窗口都是一个QMdiSubWindow
实例,你可以在其中放入任何QWidget
。
1.1 使用步骤
- 在主窗口中放置一个
QMdiArea
,并通常将其设置为主窗口的中央部件(central widget
)。 - 创建你的“处理窗口”的内容控件(例如,一个
QTextEdit
或自定义的QWidget
)。 - 使用
QMdiArea::addSubWindow()
将内容控件包装成一个QMdiSubWindow
并添加到QMdiArea
中。 - 调用
QMdiSubWindow::show()
显示子窗口。
示例代码
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMdiArea>
#include <QMdiSubWindow>
#include <QTextEdit>
#include <QAction>
#include <QMenuBar>MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);setWindowTitle("QMdiArea 多窗口示例");// 1. 创建 QMdiArea 并设置为主窗口的中央部件mdiArea = new QMdiArea(this);setCentralWidget(mdiArea);// 2. 创建一个菜单和动作来触发新窗口的创建QAction *newAction = new QAction("新建文档", this);connect(newAction, &QAction::triggered, this, &MainWindow::createNewDocument);menuBar()->addMenu("文件")->addAction(newAction);// 可以添加更多动作来管理子窗口QAction *tileAction = new QAction("平铺窗口", this);connect(tileAction, &QAction::triggered, mdiArea, &QMdiArea::tileSubWindows);menuBar()->addMenu("窗口")->addAction(tileAction);QAction *cascadeAction = new QAction("层叠窗口", this);connect(cascadeAction, &QAction::triggered, mdiArea, &QMdiArea::cascadeSubWindows);menuBar()->addMenu("窗口")->addAction(cascadeAction);
}// 槽函数:创建新的子窗口
void MainWindow::createNewDocument()
{// 3. 创建子窗口的内容控件QTextEdit *editor = new QTextEdit();editor->setPlaceholderText("这是一个新的文档窗口");// 4. 将内容控件添加到 QMdiAreaQMdiSubWindow *subWindow = mdiArea->addSubWindow(editor);subWindow->setWindowTitle("未命名文档");subWindow->resize(400, 300); // 设置初始大小subWindow->show(); // 显示子窗口
}MainWindow::~MainWindow()
{delete ui;
}
1.2 特点
-
优点
- 真实的多窗口体验:子窗口可以自由拖动、缩放、最大化、最小化。
- 丰富的管理功能:
QMdiArea
内置了平铺(tileSubWindows
)、层叠(cascadeSubWindows
)等布局管理函数。 - 符合传统桌面应用习惯。
-
缺点
- 当子窗口过多时,可能会互相遮挡,导致用户找不到需要的窗口。
二、 QTabWidget
(标签页界面)
QTabWidget
通过标签页的形式来管理多个窗口。用户可以通过点击不同的标签来切换显示不同的内容页,所有内容都在同一个区域内显示。这在现代应用中非常流行,如浏览器、代码编辑器等。
QTabWidget
:作为标签页的容器。QWidget
:每个标签页对应的内容控件。
2.1 使用步骤
- 在主窗口中放置一个
QTabWidget
,并通常将其设置为主窗口的中央部件。 - 创建你的“处理窗口”的内容控件。
- 使用
QTabWidget::addTab()
将内容控件添加到QTabWidget
中,并为其指定一个标签名。
示例代码
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QTabWidget>
#include <QTextEdit>
#include <QAction>
#include <QMenuBar>MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);setWindowTitle("QTabWidget 多窗口示例");// 1. 创建 QTabWidget 并设置为主窗口的中央部件tabWidget = new QTabWidget(this);// 设置为可关闭标签页tabWidget->setTabsClosable(true);// 连接关闭标签页的信号connect(tabWidget, &QTabWidget::tabCloseRequested, this, &MainWindow::closeTab);setCentralWidget(tabWidget);// 2. 创建一个菜单和动作来触发新标签页的创建QAction *newAction = new QAction("新建标签页", this);connect(newAction, &QAction::triggered, this, &MainWindow::createNewTab);menuBar()->addMenu("文件")->addAction(newAction);// 初始创建一个标签页createNewTab();
}// 槽函数:创建新的标签页
void MainWindow::createNewTab()
{// 3. 创建标签页的内容控件QTextEdit *editor = new QTextEdit();editor->setPlaceholderText("这是一个新的标签页");// 4. 将内容控件添加到 QTabWidgetint index = tabWidget->addTab(editor, "未命名");// 切换到新创建的标签页tabWidget->setCurrentIndex(index);
}// 槽函数:关闭标签页
void MainWindow::closeTab(int index)
{if (index >= 0) {QWidget *widget = tabWidget->widget(index);tabWidget->removeTab(index);delete widget; // 必须手动删除控件,否则会内存泄漏}
}MainWindow::~MainWindow()
{delete ui;
}
2.2 特点
-
优点
- 界面整洁:所有内容都在一个窗口内,不会相互遮挡。
- 切换方便:通过点击标签即可快速切换,非常直观。
- 节省空间:尤其适合屏幕空间有限的情况。
-
缺点
- 缺乏多窗口的自由度,所有内容都被限制在一个固定区域。
- 标签过多时,标签栏会变得拥挤,需要滚动才能访问。
2.3 如何选择
特性 | QMdiArea (多文档界面) | QTabWidget (标签页界面) |
---|---|---|
视觉体验 | 主窗口内的独立浮动/平铺窗口 | 单一窗口内的多个标签页 |
窗口管理 | 可自由拖动、缩放、最大化、最小化 | 只能通过标签切换,不能自由移动 |
空间利用 | 窗口可能重叠,显得杂乱 | 整洁有序,充分利用空间 |
适用场景 | 需要同时查看和比较多个文档的应用(如CAD、图片编辑) | 一次只需要关注一个任务,但任务较多的应用(如浏览器、代码编辑器) |
简单来说:
- 如果你的应用需要提供类似 Photoshop 的工作区,让用户可以同时看到并操作多个独立的文档,选择
QMdiArea
。 - 如果你的应用更像一个 Web 浏览器,用户通过标签页在不同的内容之间切换,选择
QTabWidget
。