C/C++ Qt MdiArea 多窗体组件应用
MDI多窗体组件,主要用于设计多文档界面应用程序,该组件具备有多种窗体展示风格,其实现了在父窗体中内嵌多种子窗体的功能,使用MDI组件需要在UI界面中增加mdiArea控件容器,我们所有的窗体创建与操作都在这个容器内进行,如下我们将具体介绍该组件的常用使用技巧。
MDI窗体控件类似于画布,该控件只具备展示窗体的功能,无法实现生成窗体,所以我们需要在项目中手动增加自定义的Dialog对话框,并对该对话框进行一定的定制。

这个Dialog对话框我们只增加两个功能,一个Dialog::currentFileName()获取窗体标题,另一个Dialog::SetData(QString data)设置数据到编辑框,代码实现如下.
#include "dialog.h"
#include "ui_dialog.h"
Dialog::Dialog(QWidget *parent) :QDialog(parent),ui(new Ui::Dialog)
{
ui->setupUi(this);
this->setWindowTitle("New Doc <By: LyShark >"); // 窗口标题
this->setAttribute(Qt::WA_DeleteOnClose); // 关闭时自动删除
this->setFixedSize(200,100); // 设置窗体大小
// this->setWindowIcon(QIcon(":/image/1.ico"));
}
Dialog::~Dialog()
{
delete ui;
}
// 获取窗体标题
// By: LyShark
QString Dialog::currentFileName()
{
QString title = this->windowTitle();
return title;
}
// 设置编辑框内容
// https://www.cnblogs.com/lyshark
void Dialog::SetData(QString data)
{
ui->lineEdit->setText(data);
}
接着我们开始绘制这个程序的主界面,在toolBar中增加相应的菜单栏,并在主窗体中放入mdiArea容器组件。

窗体中的顶部菜单栏,我们需要手动定义一下他们所具备的功能名称等。

当程序启动后,程序调用MainWindow初始化这个窗体,初始化代码如下:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "dialog.h"
#include <iostream>
#include <QCloseEvent>
// 如果直接关闭,则清空所有对话框
// https://www.cnblogs.com/lyshark
void MainWindow::closeEvent(QCloseEvent *event)
{
ui->mdiArea->closeAllSubWindows();
event->accept();
}
// By: LyShark
MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{
ui->setupUi(this);
this->setCentralWidget(ui->mdiArea);
//this->setWindowState(Qt::WindowMaximized); //窗口最大化显示
ui->mainToolBar->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
ui->mdiArea->setViewMode(QMdiArea::SubWindowView); //子窗口模式
}
MainWindow::~MainWindow()
{
delete ui;
}
代码运行效果如下:

用户新建窗体执行MainWindow::on_actionOpen_triggered()事件,关闭窗体时则执行MainWindow::on_actionClose_triggered()事件。
// 新建窗体
void MainWindow::on_actionOpen_triggered()
{
Dialog *formDoc = new Dialog(this); //
ui->mdiArea->addSubWindow(formDoc); //文档窗口添加到MDI
formDoc->show(); //在单独的窗口中显示
}
// 关闭全部
void MainWindow::on_actionClose_triggered()
{
ui->mdiArea->closeAllSubWindows(); //关闭所有子窗口
}
代码运行效果如下:

当用户点击MDI模式时,我们则执行以下代码,将所有已存在的窗体合并为一个类似于TabWidget的窗体组件。
// 转为MID模式
void MainWindow::on_actionMID_triggered(bool checked)
{
// Tab多页显示模式
if (checked)
{
ui->mdiArea->setViewMode(QMdiArea::TabbedView); // Tab多页显示模式
ui->mdiArea->setTabsClosable(true); // 页面可关闭
ui->actionLine->setEnabled(false);
ui->actionTile->setEnabled(false);
}
// 子窗口模式
else
{
ui->mdiArea->setViewMode(QMdiArea::SubWindowView); // 子窗口模式
ui->actionLine->setEnabled(true);
ui->actionTile->setEnabled(true);
}
}
代码运行效果如下:

窗体级联模式则是将窗体并排排列在一起,我们只需要调用ui->mdiArea->cascadeSubWindows();方法即可实现.
// 级联模式
void MainWindow::on_actionLine_triggered()
{
ui->mdiArea->cascadeSubWindows();
}
代码运行效果如下:

平铺模式同样使用ui->mdiArea->tileSubWindows();即可实现转换。
// 平铺模式
void MainWindow::on_actionTile_triggered()
{
ui->mdiArea->tileSubWindows();
}
代码运行效果如下:

最后一个功能是主窗体发送数据到子窗体,该功能的实现需要两个函数。
- on_mdiArea_subWindowActivated 实现设置主窗体名字到自身
- on_actionSendMsg_triggered 实现主窗体发送消息到子窗体内
// 当子窗体打开时获取到其窗体标题
// By: LyShark
void MainWindow::on_mdiArea_subWindowActivated(QMdiSubWindow *arg1)
{
Q_UNUSED(arg1);
// 若子窗口个数为零,则将statusBar置空
if (ui->mdiArea->subWindowList().count()==0)
{
ui->statusBar->clearMessage();
}
else
{
// 如果不为0则显示主窗口的文件名
Dialog *formDoc=static_cast<Dialog*>(ui->mdiArea->activeSubWindow()->widget());
ui->statusBar->showMessage(formDoc->currentFileName());
}
}
// 对选中窗体发送数据
// https://www.cnblogs.com/lyshark
void MainWindow::on_actionSendMsg_triggered()
{
// 先获取当前MDI子窗口
Dialog *formDoc;
// 如果打开则获取活动窗体
if (ui->mdiArea->subWindowList().count() > 0)
{
formDoc=(Dialog*)ui->mdiArea->activeSubWindow()->widget();
// 对活动窗体设置数据
formDoc->SetData("hello lyshark");
}
}
代码运行效果如下:

C/C++ Qt MdiArea 多窗体组件应用的更多相关文章
- Qt无边框窗体-模拟模态窗体抖动效果
目录 一.概述 二.效果展示 三.功能实现 四.相关文章 原文链接:Qt无边框窗体-模拟模态窗体抖动效果 一.概述 用Qt开发windows客户端界面确实是一大利器,兼顾性能的同时,速度相对来说也不错 ...
- C/C++ Qt 自定义Dialog对话框组件应用
在上一篇博文 <C/C++ Qt 标准Dialog对话框组件应用> 中我给大家演示了如何使用Qt中内置的标准对话框组件实现基本的数据输入功能. 但有时候我们需要一次性修改多个数据,使用默认 ...
- qt qml qchart 图表组件
qt qml qchart 图表组件 * Author: Julien Wintz * Created: Thu Feb 13 23:41:59 2014 (+0100) 这玩意是从chart.js迁 ...
- 第30课 Qt中的文本编辑组件
1. 3种常用的文本编辑组件的比较 单行文本支持 多行文本支持 自定义格式支持 富文本支持 QLineEdit (单行文本编辑组件) Yes No No No QPlainTextEdit (多行普通 ...
- QT实现不规则窗体
看到网上有很多不规则窗体的实现,效果很酷.于是使用QT也实现了一个,QT的不规则窗体实现非常简单,只需要设置一个mask(遮掩)图片,这个图片的格式可以使用png或bmp格式,我使用了png格式,默认 ...
- ZK框架笔记3、窗体组件
<window title="My First window" border="normal" width="200px" closa ...
- Qt无边框窗体-最大化时支持拖拽还原
目录 一.概述 二.效果展示 三.demo制作 1.设计窗体 2.双击放大 四.拖拽 五.相关文章 原文链接:Markdown模板 一.概述 用Qt进行开发界面时,既想要实现友好的用户交互又想界面漂亮 ...
- QT使用提升自定义组件
QT使用提升自定义组件 QTC++QT自定义 QT 组件提升来实现自定义功能 介绍 我们在使用QT设置界面之后,往往需要自己实现一些方法,如果是单独 的还好,但是如果遇到很多同类型的都有需求, 比如 ...
- Qt 如何使窗体初始最大化
Qt 如何使窗体初始最大化 使用以下函数即可解决: void QWidget::setWindowState ( Qt::WindowStateswindowState ) 这样的函数,通过它可以设置 ...
随机推荐
- 面试官:Java从编译到执行,发生了什么?
面试官:今天从基础先问起吧,你是怎么理解Java是一门「跨平台」的语言,也就是「一次编译,到处运行的」? 候选者:很好理解啊,因为我们有JVM. 候选者:Java源代码会被编译为class文件,cla ...
- 远程设备管理opendx平台搭建-appium和adb的安装
多年不见了,说起来也有3年了我又开始写博客了,这几年我还是没啥长进,还是干测试,但是测试行业的话,我已经成了一个测开了,也在搭建自己的测试网站 本系列文章讲述的是一个系列的第一部分,最终可以搭建一整套 ...
- SharkCTF2021 pwn“初见”1
(无内鬼 今日不想学了 水一篇) nc nc nc easyoverflow Intoverflow
- ScatterLayout:分散布局在py中的引用
""" ScatterLayout:分散布局 """ from kivy.app import App from kivy.uix.scat ...
- 验证域用户(C#)
代码如下: using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Intero ...
- [对对子队]会议记录4.18(Scrum Meeting9)
今天已完成的工作 何瑞 工作内容:修复了一些关卡1的bug 相关issue:搭建关卡1 相关签入:4.18签入1 4.18签入2 梁河览 工作内容:实现了音量控制,添加了BGM 相 ...
- 使用Mybatis的TypeHandler加解密数据
使用Mybatis的TypeHandler加解密数据 一.背景 二.解决方案 三.需求 四.实现思路 1.编写一个实体类,凡是此实体类的数据都表示需要加解密的 2.编写一个加解密的`TypeHandl ...
- SpringBoot小知识点
记录SpringBoot的小知识点 一.在 Spring 上下文刷新之前设置一些自己的环境变量 1.实现 EnvironmentPostProcessor 接口 2.spring.factories ...
- Noip模拟49 2021.9.7
T1 reverse 又一道板子打假的挂分题,直接挂到倒二.. 考场上思路神奇,居然想到用$bfs$建边然后跑最短路, 其实当时也想到了直接$bfs$,但是不知道为啥觉得$dij$屌就没直接打$bfs ...
- TVS管相关知识
在设计中,使用到了TVS管,在之前的设计中没有特别关注TVS管.今天查了一些资料,算是简单的有个了解. TVS管是一种保护器件.它的英文全称为 transient voltage suppressor ...