Qt 的MDI 多文档窗口
一、MDI简介
MDI就是多文档界面(Multi-document Interface,MDI)应用程序
MDI就是在主窗口里创建多个同类型的MDI子窗口,这些MDI子窗口在主窗口里显示,并共享主窗口上工具栏和菜单等操作功能,主窗口上的操作都针对当前活动的MDI子窗口进行
二、QMdiArea组件
设计MDI应用程序需要在主窗口工作区放置一个QMdiArea作为MDI子窗体的容器
所以我们需要事先创建窗体类对象,然后将窗口类通过addSubWindow函数添加到MDIArea组件中,然后再调用窗口类的show函数显示窗体
三、MDI的一些注意事项
当在主窗口中关闭一个MDI子窗口时,这个MDI窗口对象都会删除。也可以使用setAttribute(Qt::WA_DeleteOnClose);函数显示设置在关闭MDI时删除窗口对象
四、QMDIArea组件的相关函数
addSubWindow函数
此函数将一个窗口类添加到MDIArea中,然后调用窗口类的show函数显示在MDIArea中
activeSubWindow、widget函数
该函数返回当前选中的活动的子窗口,返回的是QMdiSubWindow指针对象
这样我们就可以通过activeSubWindow函数返回的QMdiSubWindow指针对象,间接通过widget函数得到该窗口的对象(但是需要强制类型转换)
QMdiSubWindow *QMdiArea::activeSubWindow() const
//头文件:#include <QMdiSubWindow>
QWidget *QMdiSubWindow::widget() const
subWindowList函数
此函数返回MDIArea组件中的窗口类列表
因此我们可以通过该函数再调用count函数获取当前MDIArea中的窗体数量
QList<QMdiSubWindow *> QMdiArea::subWindowList(WindowOrder order = CreationOrder) const
loadFormFile函数
当某个窗体添加到MDIArea中之后,就可以通过此函数加载一个文件的内容
参数为QString对象,该对象是通过QFileDialog::getOpenFileName函数打开的
closeAllSubWindows函数
通过此函数关闭MDIArea组件中的所有窗口
void QMdiArea::closeAllSubWindows()
tabsClosable()、setTabsClosable函数
tabsClosable:返回当前的MDIArea中的某个窗口是否可以关闭
setTabsClosable:设置当前的MDIArea中的某个窗口是否可以关闭
bool tabsClosable() const
void setTabsClosable(bool closable)
viewMode、setViewMode函数
viewMode:返回当前MDIArea中某个窗口的显示模式
setViewMode:设置当前MDIArea中某个窗口的显示模式
ViewMode viewMode() const
void setViewMode(ViewMode mode)
ViewMode 类型如下:
QMdiArea::TabbedView //Tab多页显示模式
QMdiArea::SubWindowView //子窗口模式
窗口默认显示为“子窗口模式”显示,Tab多页显示模式如下图所示:
cascadeSubWindows、tileSubWindows函数
cascadeSubWindows:窗口级联模式展开显示
tileSubWindows:窗口平铺模式展开显示
void QMdiArea::cascadeSubWindows()
void QMdiArea::tileSubWindows()
textCut、setEditFont等函数
当我们将窗口添加到MDIArea中之后,就可以调用这些函数来对窗口的字体进行格式化设置、剪切、复制
五、QMDIArea组件的信号函数
subWindowActivated信号函数
当前活动窗口切换时触发此信号函数,利用此信号可以在活动窗口切换时进行一些处理
subWindowActivated(QMdiSubWindow *arg1)
演示案例
一、文档类窗体的设计
这个窗体类是用来放在主窗体的MDIArea组件中的
①窗体创建与设计
类中只放置一个QPlainTextEdit组件,并以水平布局填充整个窗口
②类的初始化
class QFormDoc : public QWidget
{
Q_OBJECT
private:
QString mCurrentFile; //当前文件名
bool mFileOpened=false; //判断当前文件是否已打开,默认为未打开
public:
explicit QFormDoc(QWidget *parent = 0);
~QFormDoc();
void loadFormFile(QString &aFileName); //打开文件,并将文件内容读取plainTextEdit中
QString currentFileName(); //返回当前文件名
bool isFileOpened(); //判断文件是否已打开
void setEditFont(); //设置字体
void textCut(); //cut
void textCopy(); //copy
void textPaste(); //paste
private:
Ui::QFormDoc *ui;
};
③相关函数的定义
//构造函数
QFormDoc::QFormDoc(QWidget *parent) :
QWidget(parent),
ui(new Ui::QFormDoc)
{
ui->setupUi(this);
this->setWindowTitle("New Doc"); //窗口标题
this->setAttribute(Qt::WA_DeleteOnClose);//关闭时自动删除(备注:不论是否设置此项,MDI在关闭时,都会删除窗口对象)
}
//析构函数
QFormDoc::~QFormDoc()
{
QMessageBox::information(this,QStringLiteral("信息"),
QStringLiteral("文档窗口被释放"));//窗口关闭之后提示
delete ui;
}
//打开文件,并将文件内容读取plainTextEdit中
void QFormDoc::loadFormFile(QString &aFileName)
{
QFile aFile(aFileName);
if(aFile.open(QIODevice::ReadOnly|QIODevice::Text))
{
//读取文件并讲内容放入plainTextEdit
QTextStream aStream(&aFile);
ui->plainTextEdit->clear();
ui->plainTextEdit->setPlainText(aStream.readAll());
aFile.close();
//根据文件名获取文件信息,将文件名设置MDI窗体的标题
mCurrentFile=aFileName;
QFileInfo fileInfo(aFileName);
QString str=fileInfo.fileName();
this->setWindowTitle(str);
mFileOpened=true;
}
}
//返回当前文件名称
QString QFormDoc::currentFileName()
{
return mCurrentFile;
}
//判断当前文件是否打开,打开返回true
bool QFormDoc::isFileOpened()
{
return mFileOpened;
}
//设置plainTextEdit的梯子
void QFormDoc::setEditFont()
{
QFont font=ui->plainTextEdit->font();
bool ok;
font=QFontDialog::getFont(&ok,font); //打开字体设置窗体
ui->plainTextEdit->setFont(font);
}
//对文档的剪切、复制、黏贴
void QFormDoc::textCut()
{
ui->plainTextEdit->cut();
}
void QFormDoc::textCopy()
{
ui->plainTextEdit->copy();
}
void QFormDoc::textPaste()
{
ui->plainTextEdit->paste();
}
二、主窗体设计
①主窗体界面设计
主窗体中是一个MDI Area组件
因为要在主窗口调用刚才自己设计的MDI窗体类QFormDoc,所以加入下面的头文件
②Action设计
添加了以下的Action,作为主窗体的工具栏使用
③构造函数
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
this->setCentralWidget(ui->mdiArea); //让MDI Area组件填充满主窗口区域
this->setWindowState(Qt::WindowMaximized); //设置窗体最大化
//让工具按钮的文字处于图标的下方
ui->mainToolBar->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
}
④新建文档按钮的触发函数
点击此按钮,在MDIArea中创建一个新的窗体
void MainWindow::on_actDoc_New_triggered()
{
QFormDoc *formDoc=new QFormDoc(this); //创建文档窗口对象
ui->mdiArea->addSubWindow(formDoc); //将文档窗口添加到MDI中
formDoc->show(); //显示MDI窗体
}
⑤打开文档按钮的触发函数
点击此按钮,选择一个文档,并将文档的内容显示到MDIArea的窗体中
void MainWindow::on_actDoc_Open_triggered()
{
bool needNew=false; //是否需要新建子窗口
QFormDoc *formDoc;
if(ui->mdiArea->subWindowList().count()>0) //如有mdiArea组件中已经有窗口
{
formDoc=(QFormDoc*)ui->mdiArea->activeSubWindow()->widget();//获取当前鼠标所选中的窗口对象
needNew=formDoc->isFileOpened(); //needNew为false,表示不需要新建子窗口
}
else
needNew=true; //mdiArea组件中还没有窗口,需要新建
//打开一个文件
QString curPath=QDir::currentPath();
QString aFileName=QFileDialog::getOpenFileName(this,
QStringLiteral("打开一个文件"),curPath,
QStringLiteral("C程序文件(*.h *.cpp);;所有文件(*.*)"));
if(aFileName.isEmpty())
return;
if(needNew) //如果需要新建窗口,那么新建窗口
{
formDoc=new QFormDoc(this);
ui->mdiArea->addSubWindow(formDoc); //将新建的窗口变为当前的操作窗口
}
formDoc->loadFormFile(aFileName); //通过文件名加载文件内容
formDoc->show(); //显示窗口
ui->actCut->setEnabled(true);
ui->actCopy->setEnabled(true);
ui->actPaste->setEnabled(true);
ui->actFont->setEnabled(true);
}
⑥关闭全部按钮的触发函数
点击此按钮,关闭MDI中所有窗体
void MainWindow::on_actCloseAll_triggered()
{
ui->mdiArea->closeAllSubWindows();//关闭全部子窗口
}
⑦MDI模式按钮的触发函数
void MainWindow::on_actViewMode_triggered(bool checked)
{
if(checked)
{
ui->mdiArea->setViewMode(QMdiArea::TabbedView);//Tab多页显示模式
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 MainWindow::on_actCascade_triggered()
{
ui->mdiArea->cascadeSubWindows();
}
//窗体平铺显示
void MainWindow::on_actTile_triggered()
{
ui->mdiArea->tileSubWindows();
}
级联展开
平铺展开
⑨其他按钮触发函数
void MainWindow::on_actCut_triggered()
{
//获取当前的活动窗口
QFormDoc* formDoc=(QFormDoc*)ui->mdiArea->activeSubWindow()->widget();
formDoc->textCut();//剪切
}
void MainWindow::on_actFont_triggered()
{
QFormDoc* formDoc=(QFormDoc*)ui->mdiArea->activeSubWindow()->widget();
formDoc->setEditFont();
}
⑩MDI的subWindowActivated信号函数
当前活动窗口切换时产生触发此信号函数,利用该信号函数可以在活动窗口切换时进行一些处理
void MainWindow::on_mdiArea_subWindowActivated(QMdiSubWindow *arg1)
{
if(ui->mdiArea->subWindowList().count()==0)//如果当前MDI中没有窗口了
{
//编辑按钮都不能使用
ui->actCut->setEnabled(false);
ui->actCopy->setEnabled(false);
ui->actPaste->setEnabled(false);
ui->actFont->setEnabled(false);
ui->statusBar->clearMessage();
}
else
{
//当窗口切换时,将当前活动的窗口打开的文件名显示到statusBar中
QFormDoc *formDoc=static_cast<QFormDoc*>(
ui->mdiArea->activeSubWindow()->widget());
ui->statusBar->showMessage(formDoc->currentFileName());
}
url 网址
http://www.skcircle.com/?id=978
Qt 的MDI 多文档窗口的更多相关文章
- 2015.12.14 MDI(多文档窗口结构)设置基本解决,折腾一天,部分解决存在已久的问题。但效果仍不如临时航线的MDI窗体结构。
创建从一个窗口弹出多个子窗口的结构叫MDI窗体结构 如果不按MDI结构管理,最简单的做法是: 在窗体A上添加菜单或按钮,在菜单或按钮事件中添加弹出B窗体代码: B b = new B(); b.sho ...
- 利用Qt Assistant 定制帮助文档
为了将Qt Assistant定制为自己应用程序的帮助文档浏览器.需要完成以下几步: 一.导入HTML格式的帮助文档 (1)首先,针对自己的应用程序创建HTML格式的帮助文档,请参见<Doxyg ...
- Word2003文档窗口分成上下两个独立的窗口
http://www.officezu.com/word/2003/index16.html 拆分窗口就是把一个Word2003文档窗口分成上下两个独立的窗口,从而可以通过两个Word2003文档窗口 ...
- 2.QT中操作word文档
Qt/Windows桌面版提供了ActiveQt框架,用以为Qt和ActiveX提供完美结合.ActiveQt由两个模块组成: A QAxContainer模块允许我们使用COM对象并且可以 ...
- 关于MDI多文档程序的一些思考
MDI程序的框架 客户窗口是一个预定义的窗口类(MDICLIENT),它是框架窗口的子窗口同时也是各个子文档窗口的父窗口.框架窗口和各个子文档窗口都是自定义的窗口类. MDI程序中的一些要点 窗口中的 ...
- MDI多文档窗体--在一个窗体中装载多个窗体
创建MDI窗体之前,首先要明确两个概念:父窗体和子窗体,在MDI窗体中,起到容器作用的窗体被称为“父窗体”, 可放在父窗体中的其他窗体被称为子窗体,也成为MDI子窗体.当应用程序启动时,首先会显示父窗 ...
- C#-Mdi多文档窗体及其子窗体的排列 ---ShinePans
MdiLayout枚举成员及说明 Casecade s全部Mdi层叠在父窗体 TileHorizontal 水平平铺 TitleVertical 垂直平铺 Form1.cs (mdi) using S ...
- Qt Style Sheets帮助文档 Overview
Qt Style Sheets are a powerful mechanism that allows you to customize the appearance of widgets, in ...
- C# Winfrom MDI(多文档界面)
1.首先设置父级Form1界面,只需要将该界面的IsMdiContainer属性设置为true: 2.设置按钮的事件来打开子级的窗口Form2,Form3等等: 3.在From1内设置一个容器pane ...
随机推荐
- 从新建文件夹开始构建ShadowPlay Engine游戏引擎(3)
本篇序言 各位可能看到博文的名字换了,也就是引擎名字换了,其实是在下想到了一个更棒的名字:皮影戏(ShadowPlay),取这个名字的含义是因为,游戏中的角色(Puppet)不也是由于我们的操作而动起 ...
- python pandas inplace参数
'''pandas 中 inplace 参数在很多函数中都会有,它的作用是:是否在原对象基础上进行修改 inplace = True:不创建新的对象,直接对原始对象进行修改: inplace ...
- 10、Java——内部类
1.类中定义类 (1)当一类中的成员,作为另外一种事物的时候,这个成员就可以定义为内部类. (2)分类:①成员内部类 ②静态内部类 ③私有内部类 ④局部内部类 ⑤匿名内部类 ⑥Lambda表达式 ...
- 剑指offer-子树结构
描述 输入两棵二叉树A,B,判断B是不是A的子结构.(ps:我们约定空树不是任意一个树的子结构) 求解思路: 首先肯定是找到树A中等于树B根节点的节点. A和B按照同样的遍历顺序比较,如果全相同A ...
- 基于小熊派Hi3861鸿蒙开发的IoT物联网学习【四】
一.互斥锁基本概念: 1.互斥锁又称互斥型信号量,是一种特殊的二值性信号量[二值型信号量可以理解为任务与中断间或者两个任务间的标志,该标志非"满"即"空"],用 ...
- SQL注入之二次,加解密,DNS等注入
#sql注入之二次注入 1.注入原理 二次注入可以理解为,构造恶意数据存储在数据库后,恶意数据被读取并进入到了SQL查询语句所导致的注入.恶意数据插入到数据库时被处理的数据又被还原并存储在数据库中,当 ...
- C语言复习(二)
引言: 不会将每一个部分都详述,只关注于一些自己认为重要的或常错的,若有不足,还望指出 switch()细节:括号内必须是整型或枚举类型:遇到break才会跳出:case包含的必须是常量 contin ...
- C++ //深拷贝与浅拷贝 //浅拷贝 : 简单的赋值拷贝操作 //深拷贝: 在堆区重新申请空间 进行拷贝操作
1 //深拷贝与浅拷贝 2 3 //浅拷贝 : 简单的赋值拷贝操作 4 //深拷贝: 在堆区重新申请空间 进行拷贝操作 5 6 7 #include <iostream> 8 using ...
- GUI编程简介
GUI编程(淘汰) GUI编程怎么学? 这是什么 它怎么玩 该如何去在我们平时运用 class -- 可阅读 组件 窗口 弹窗 面板 文本框 列表框 按钮 图片 监听事件 鼠标 键盘事件 破解工具 1 ...
- Redisson实战-BloomFilter
1. 简介 布隆过滤器是防止缓存穿透的方案之一.布隆过滤器主要是解决大规模数据下不需要精确过滤的业务场景,如检查垃圾邮件地址,爬虫URL地址去重, 解决缓存穿透问题等. 布隆过滤器:在一个存在一定数量 ...