Qt框架中MDI多文档界面的开发详解
创作时间:
作者:
@小白创作中心
Qt框架中MDI多文档界面的开发详解
引用
CSDN
1.
https://blog.csdn.net/qq_74047911/article/details/139519140
Qt框架提供了MDI(多文档界面)功能,可以更方便地实现多个窗口的开发。MDI使用QMdiArea作为多个子窗体的容器,这些子窗体可以共享主窗体的工具栏和菜单栏,非常适合需要进行多个文档编辑的场景,比如类似VS的编辑界面。
应用场景
类似于VS的界面功能,工具栏的功能可以对每个文档使用。
界面设计
在MainWindow的构造函数中,将QMdiArea设置为中心组件,并将其最大化显示。
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的编辑界面。
热门推荐
会计分录编制的核心技巧与常见误区
福州的家乡民俗有哪些?福州:探秘千年古都的独特民俗风情!
应届生报考国考都有什么优势?
焊锡膏的厚度对焊接质量的影响
在东北,还留有多少日本人后代?命运如何?为何没成为少数民族?
纳米级氧化锆与非纳米氧化锆的区别
中国十大核电站:从秦山到阳江的核电发展历程
成熟芯片的全球博弈:产能过剩到供应链依赖
怎么看电脑是32位还是64位
高中生如何提高英语写作技巧?高考英语应试拿分攻略,三大要点
聂远凭《大河之水》出圈,不仅演技获赞,和杨蓉的配合也尽显默契
普罗帕酮:揭秘治疗效果与日常保健
马克笔涂在皮肤上会不会中毒,不会中毒但会导致皮肤发干
老年人能力评估系统的数据安全性如何保障?
国债逆回购:安全稳健的理财工具详解
福州的家乡民俗有哪些?福州:探秘千年古都的独特民俗风情!
揭秘广西“狼兵”:从古代烟瘴之地走出的抗日劲旅
如何分析囚徒困境的解决策略及其应用场景?这些策略如何在实际中进行优化?
狗狗断奶注意四大事项 成长第一步
皮肤管理打卡照片怎么拍?这份专业指南手把手教你掌握拍摄技巧
“黑科技”破解“三断”极端场景难题,这场国家级应急通信演练火爆出圈
半导体负载板的常见缺陷及测试方法
量子纠缠:神秘背后的科学之谜与挑战
Win7如何更新补丁?探索Windows 7最新系统补丁的获取与安装方法
中医基础医学理论:养生的基本原则形神共养
教你认识美妙的罗勒精油
同位素:化学与物理中的重要概念
局部放电检测中的频段解析:特高频、高频与超声波技术详解
中介合同和网签合同哪个为准?
曹操为何归葬于殷商之都安阳?