MDI多文档界面开发
- 一.应用场景
- 二.界面设计
- 三.界面类设计
- 四.实现功能
- 1.新建文档
- 2.打开文件
- 3.关闭所有
- 4.编辑功能
- 5.MDI页模式
- 6.瀑布展开模式
- 7.平铺模式
- 五.总结
一.应用场景
类似于vs的界面功能,工具栏的功能可以对每个文档使用!
二.界面设计
老规矩,边做项目边学!
目标图:
需要蔬菜的可以dd我!
界面设计:
同时设为中心组件和最大化的状态设置!
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
setCentralWidget(ui->mdiArea);
setWindowState(Qt::WindowMaximized);
}
三.界面类设计
添加一个纯文本编辑器
并设置窗口边距:
四.实现功能
1.新建文档
注意界面类设计的头文件.
运行结果:
2.打开文件
先来说一说打开文件的逻辑
如果没有窗口,就先新建一个窗口,再将文件内容写入
如果有窗口,看是否已经写入了文件,如果有就重新创建一个窗口
没有写入就直接写入.
#include "formdoc.h"
#include <QMdiSubWindow>
#include <QFileDialog>
....
void MainWindow::on_actionOpen_triggered()
{
bool needForm=false;//是否需要新建窗口
FormDoc*form=NULL;//变化的指向
if(ui->mdiArea->subWindowList().count()==0)//如果没有窗口就要新建
{
needForm=true;
}
else//有窗口的情况下
{
form=(FormDoc*)ui->mdiArea->activeSubWindow()->widget();//指向激活的窗口,也就是当前点击的子窗口,需要用到头文件
if(form->fileWrite())//如果文件已经写入就需要重新创建一个窗口
{
needForm=true;
}
}
//获取文件路径名
QString fileName=QFileDialog::getOpenFileName(this,"打开一个文件",QDir::currentPath(),
"源文件(*.h *.cpp);;文本文件(*.txt);;所有文件(*.*)");
if(fileName.isEmpty())
{
return;
}
if(needForm)
{
form=new FormDoc(this);//创建新的窗口
ui->mdiArea->addSubWindow(form);//添加到MDI容器
}
form->loadFile(fileName);//将文件写入窗口
form->show();
}
面向对象的思想对formDoc窗口进行操作和读取数据.
#ifndef FORMDOC_H
#define FORMDOC_H
#include <QWidget>
namespace Ui {
class FormDoc;
}
class FormDoc : public QWidget
{
Q_OBJECT
public:
explicit FormDoc(QWidget *parent = nullptr);
~FormDoc();
bool fileWrite();//文件是否写入
void loadFile(const QString&fileName);//写入文件到窗口
private:
Ui::FormDoc *ui;
bool m_fileWrite=false;
};
#endif // FORMDOC_H
函数实现:
#include <QTextStream>
#include <QFileInfo>
...
bool FormDoc::fileWrite()
{
return this->m_fileWrite;
}
void FormDoc::loadFile(const 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();
//设置窗口的主题
QFileInfo fileName;
QString name=fileName.fileName();
this->setWindowTitle(name);
//写了文件,姚重新创造一个窗口
this->m_fileWrite=true;
}
}
运行结果:
3.关闭所有
void MainWindow::on_actionCloseAll_triggered()
{
ui->mdiArea->closeAllSubWindows();
}
4.编辑功能
因为纯文本编辑器组件本来就有这些功能,所以我们可以用面向对象的思想在formdoc窗口来设置接口!
void MainWindow::on_actionCut_triggered()
{
FormDoc*form=(FormDoc*)ui->mdiArea->activeSubWindow()->widget();//选中的窗体
form->cut();
}
void MainWindow::on_actionCopy_triggered()
{
FormDoc*form=(FormDoc*)ui->mdiArea->activeSubWindow()->widget();//选中的窗体
form->copy();
}
void MainWindow::on_actionPaste_triggered()
{
FormDoc*form=(FormDoc*)ui->mdiArea->activeSubWindow()->widget();//选中的窗体
form->paste();
}
void MainWindow::on_actionFont_triggered()
{
FormDoc*form=(FormDoc*)ui->mdiArea->activeSubWindow()->widget();//选中的窗体
form->setFont();
}
formdoc.h
#ifndef FORMDOC_H
#define FORMDOC_H
#include <QWidget>
namespace Ui {
class FormDoc;
}
class FormDoc : public QWidget
{
Q_OBJECT
public:
explicit FormDoc(QWidget *parent = nullptr);
~FormDoc();
bool fileWrite();//文件是否写入
void loadFile(const QString&fileName);//写入文件到窗口
void cut();
void copy();
void paste();
void setFont();
private:
Ui::FormDoc *ui;
bool m_fileWrite=false;
};
#endif // FORMDOC_H
formdoc.cpp
#include "formdoc.h"
#include "ui_formdoc.h"
#include <QTextStream>
#include <QFileInfo>
#include <QFontDialog>
FormDoc::FormDoc(QWidget *parent) :
QWidget(parent),
ui(new Ui::FormDoc)
{
ui->setupUi(this);
this->setAttribute(Qt::WA_DeleteOnClose);//关闭窗口时同时销毁
}
FormDoc::~FormDoc()
{
delete ui;
}
bool FormDoc::fileWrite()
{
return this->m_fileWrite;
}
void FormDoc::loadFile(const 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();
//设置窗口的主题
QFileInfo fileName;
QString name=fileName.fileName();
this->setWindowTitle(name);
//写了文件,姚重新创造一个窗口
this->m_fileWrite=true;
}
}
void FormDoc::cut()
{
ui->plainTextEdit->cut();
}
void FormDoc::copy()
{
ui->plainTextEdit->copy();
}
void FormDoc::paste()
{
ui->plainTextEdit->paste();
}
void FormDoc::setFont()
{
bool ok;
QFont font=ui->plainTextEdit->font();
font=QFontDialog::getFont(&ok,font);
ui->plainTextEdit->setFont(font);
}
运行结果:
5.MDI页模式
void MainWindow::on_actionMDI_triggered(bool checked)
{
if(checked)
{
ui->mdiArea->setViewMode(QMdiArea::TabbedView);//设置为页面模式
//页面模式不能使用展开和平铺
ui->actionShow->setEnabled(false);
ui->actionTile->setEnabled(false);
ui->mdiArea->setTabsClosable(true);//页有关闭按钮
}
else
{
ui->mdiArea->setViewMode(QMdiArea::SubWindowView);//设置为页面模式
ui->actionShow->setEnabled(true);
ui->actionTile->setEnabled(true);
ui->mdiArea->setTabsClosable(false);//页有关闭按钮
}
}
运行结果:
6.瀑布展开模式
void MainWindow::on_actionShow_triggered()
{
ui->mdiArea->cascadeSubWindows();
}
运行结果:
7.平铺模式
void MainWindow::on_actionTile_triggered()
{
ui->mdiArea->tileSubWindows();
}
运行结果:
哈哈,搞完了,感觉有的像监控,哈哈!
五.总结
Qt提供了MDI(多文档界面),可以更方便的实现多个窗口的开发
MDI使用QMdiArea作为多个子窗体的容器。
这些子窗体,可以同享使用主窗体的工具栏和菜单栏,
适合,需要进行多个文档编辑的场景,类似VS的编辑界面。
安静 既是道路,也是终点!