简 述: 了解 多文档界面MDI(Multi-document Interface)的实现,QMdiArea
使用,书写一个简单地例子;然后写了一个小的Qt例子,用来实现和验证它的空间的一些属性和功能的用法。
[TOC]
本文初发于 “偕臧的小站“,同步转载于此。
系统环境:
编程环境: MacOS 10.14.6 (18G103)
编程软件: Qt 5.9.8
, Qt Creator 4.8.2
MDI(Multi-document Interface)控件:
MDI(Multi-document Interface)
是传统的多文档界面应用程序,而Qt为此提供了支持;他们可以共享一个主窗口,以及菜单栏,工具栏等。而 设计一个MDI的应用程序就是需要在主窗口的工作去放一个QMdiArea控件作为子窗口的容器。
运行效果:
这里放下一张运行的图片
源码分析:
两个头文件的类如下:
lass ExMDI : public QWidget
{
Q_OBJECT
public:
explicit ExMDI(QWidget *parent = nullptr);
~ExMDI();
void loadFromFile(QString& fileName); //打开文件
QString currentFileName(); //返回当前文件名
bool isFileOpended(); //文件已经打开
void setEditFont();
void textCut();
void textCopy();
void textPaste();
private:
Ui::ExMDI *ui;
QString m_currentFile; //当前文件
bool m_fileOpened; //true 打开;false 未打开
};
lass ExMainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit ExMainWindow(QWidget *parent = nullptr);
~ExMainWindow();
private slots:
void on_actOpen_triggered(); //打开文档
void on_actQuit_triggered(); //退出程序
void on_actNew_triggered(); //新建MDI的子窗口
void on_actFont_triggered(); //设置字体
void on_actCut_triggered(); //剪切文本
void on_actCopy_triggered(); //复制文本
void on_actPaste_triggered(); //粘贴文本
void on_actView_triggered(bool checked); //MDI显示: Table 和 子窗口页面显示
void on_actCascade_triggered();//级联显示
void on_actTile_triggered(); //平铺显示
void on_actClose_triggered(); //关闭所有子窗口
private:
void closeEvent(QCloseEvent *e); //主窗口关闭时关闭所有子窗口
private:
Ui::ExMainWindow *ui;
};
其对应的源文件:
#include "ExMDI.h"
#include "ui_ExMDI.h"
ExMDI::ExMDI(QWidget *parent) :
QWidget(parent),
ui(new Ui::ExMDI)
{
ui->setupUi(this);
setWindowTitle("多文档界面MDI (Multi-dociment Interface) 的介绍和使用");
setAttribute(Qt::WA_DeleteOnClose); //无论是否设置关闭时候删除;在MDI中关闭一个MDI子窗口都会删除子窗口对象
this->setWindowIcon(QIcon("/Users/yuanyi/picture/发布、头像、测试图片/icon.png"));
}
ExMDI::~ExMDI()
{
delete ui;
}
//打开文件
void ExMDI::loadFromFile(QString &fileName)
{
QFile file(fileName); //文件以读的方式读出
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
QTextStream stream(&file); //以文本流方式读取文件
ui->plainTextEdit->clear();
ui->plainTextEdit->setPlainText(stream.readAll());
file.close();
m_currentFile = fileName;
QFileInfo fileInfo(fileName); //文件信息
setWindowTitle(fileInfo.fileName());
m_fileOpened = true;
}
}
QString ExMDI::currentFileName()
{
return m_currentFile;
}
bool ExMDI::isFileOpended()
{
return m_fileOpened;
}
void ExMDI::setEditFont()
{
QFont font = ui->plainTextEdit->font();
bool ok;
font = QFontDialog::getFont(&ok, font);
ui->plainTextEdit->setFont(font);
}
void ExMDI::textCut()
{
ui->plainTextEdit->cut();
}
void ExMDI::textCopy()
{
ui->plainTextEdit->copy();
}
void ExMDI::textPaste()
{
ui->plainTextEdit->paste();
}
#include "ExMainWindow.h"
#include "ui_ExMainWindow.h"
ExMainWindow::ExMainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::ExMainWindow)
{
ui->setupUi(this);
setCentralWidget(ui->mdiArea);
setWindowState(Qt::WindowMaximized);
ui->toolBar->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
}
ExMainWindow::~ExMainWindow()
{
delete ui;
}
void ExMainWindow::closeEvent(QCloseEvent *e)
{
ui->mdiArea->closeAllSubWindows(); //关闭所有子窗口
e->accept();
}
void ExMainWindow::on_actOpen_triggered()
{
bool needNew = false;
ExMDI *mdi = nullptr;
if (ui->mdiArea->subWindowList().count() > 0) { //如果有打开的主窗口,获取活动窗口
mdi = (ExMDI *)ui->mdiArea->activeSubWindow()->widget();
needNew = mdi->isFileOpended(); //文件已经打开,需要新建窗口
} else {
needNew = true;
}
QString curPath = QDir::currentPath();
QString fileName = QFileDialog::getOpenFileName(this, "打开一个文件", curPath, "C程序文件(*.h *cpp);;文本文件(*.txt);;所有文件(*.*)");
if (fileName.isEmpty())
return;
if (needNew) {
mdi = new ExMDI(this);
ui->mdiArea->addSubWindow(mdi);
}
mdi->loadFromFile(fileName);
mdi->show();
ui->actCopy->setEnabled(true);
ui->actCut->setEnabled(true);
ui->actPaste->setEnabled(true);
ui->actFont->setEnabled(true);
}
void ExMainWindow::on_actQuit_triggered()
{
close();
}
void ExMainWindow::on_actNew_triggered()
{
ExMDI *mdi = new ExMDI(this);
ui->mdiArea->addSubWindow(mdi); //添加一个子窗口MDI
mdi->show();
ui->actCopy->setEnabled(true);
ui->actCut->setEnabled(true);
ui->actPaste->setEnabled(true);
ui->actFont->setEnabled(true);
}
void ExMainWindow::on_actFont_triggered()
{
ExMDI* mdi = (ExMDI *)ui->mdiArea->activeSubWindow()->widget();
mdi->setEditFont(); //设置编写的字体文档
}
void ExMainWindow::on_actCut_triggered()
{
ExMDI* mdi = (ExMDI *)ui->mdiArea->activeSubWindow()->widget();
mdi->textCut();
}
void ExMainWindow::on_actCopy_triggered()
{
ExMDI* mdi = (ExMDI *)ui->mdiArea->activeSubWindow()->widget();
mdi->textCopy();
}
void ExMainWindow::on_actPaste_triggered()
{
ExMDI* mdi = (ExMDI *)ui->mdiArea->activeSubWindow()->widget();
mdi->textPaste();
}
void ExMainWindow::on_actView_triggered(bool checked) //MDI 模式设置
{
if (checked) { //Tab多页显示模式
ui->mdiArea->setViewMode(QMdiArea::TabbedView);
ui->mdiArea->setTabsClosable(true); //页面可以关闭
ui->actCascade->setEnabled(false);
ui->actTile->setEnabled(false);
} else {
ui->mdiArea->setViewMode(QMdiArea::SubWindowView); //子窗口模式
ui->actCascade->setEnabled(true);
ui->actTile->setEnabled(true);
}
}
void ExMainWindow::on_actCascade_triggered()
{
ui->mdiArea->cascadeSubWindows(); //窗口级联展开
}
void ExMainWindow::on_actTile_triggered()
{
ui->mdiArea->tileSubWindows(); //平铺展开
}
void ExMainWindow::on_actClose_triggered()
{
ui->mdiArea->closeAllSubWindows(); //关闭全部子窗口
}
源码下载:
https://github.com/xmuli/QtExamples 【QtMDIEx】