C/C++ Qt MdiArea 多窗体组件应用

简介: MDI多窗体组件,主要用于设计多文档界面应用程序,该组件具备有多种窗体展示风格,其实现了在父窗体中内嵌多种子窗体的功能,使用MDI组件需要在UI界面中增加mdiArea控件容器,我们所有的窗体创建与操作都在这个容器内进行,如下我们将具体介绍该组件的常用使用技巧。

MDI多窗体组件,主要用于设计多文档界面应用程序,该组件具备有多种窗体展示风格,其实现了在父窗体中内嵌多种子窗体的功能,使用MDI组件需要在UI界面中增加mdiArea控件容器,我们所有的窗体创建与操作都在这个容器内进行,如下我们将具体介绍该组件的常用使用技巧。

MDI窗体控件类似于画布,该控件只具备展示窗体的功能,无法实现生成窗体,所以我们需要在项目中手动增加自定义的Dialog对话框,并对该对话框进行一定的定制。

image.png

这个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容器组件。

image.png

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

image.png

当程序启动后,程序调用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;
}

代码运行效果如下:

image.png

用户新建窗体执行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(); //关闭所有子窗口
}

代码运行效果如下:

image.png

当用户点击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);
    }
}

代码运行效果如下:

image.png

窗体级联模式则是将窗体并排排列在一起,我们只需要调用ui->mdiArea->cascadeSubWindows();方法即可实现.

// 级联模式
void MainWindow::on_actionLine_triggered()
{
    ui->mdiArea->cascadeSubWindows();
}

代码运行效果如下:

image.png

平铺模式同样使用ui->mdiArea->tileSubWindows();即可实现转换。

// 平铺模式
void MainWindow::on_actionTile_triggered()
{
    ui->mdiArea->tileSubWindows();
}

代码运行效果如下:

image.png

最后一个功能是主窗体发送数据到子窗体,该功能的实现需要两个函数。

  • 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");
    }
}

代码运行效果如下:

image.png

目录
相关文章
|
22天前
|
存储 安全 C++
C++中的引用和指针:区别与应用
引用和指针在C++中都有其独特的优势和应用场景。引用更适合简洁、安全的代码,而指针提供了更大的灵活性和动态内存管理的能力。在实际编程中,根据需求选择适当的类型,能够编写出高效、可维护的代码。理解并正确使用这两种类型,是掌握C++编程的关键一步。
22 1
|
2月前
|
C++
C++中的封装、继承与多态:深入理解与应用
C++中的封装、继承与多态:深入理解与应用
34 1
|
2月前
【qt】Tool Box组件
【qt】Tool Box组件
20 0
|
2天前
|
数据可视化 开发者 C++
Qt(C++)使用QChart静态显示3个设备的温度变化曲线
QChart模块是Qt Charts库的基础,提供了用于创建和显示各种类型图表的类和接口。Qt Charts库是一个功能丰富、易于使用的数据可视化工具库,可以帮助开发者在应用程序中添加漂亮而又交互性强的图表。
14 1
Qt(C++)使用QChart静态显示3个设备的温度变化曲线
|
1天前
|
存储 JSON 数据可视化
Qt(C++)使用QChart动态显示3个设备的温度变化曲线
Qt的QChart是一个用于绘制图表和可视化数据的类。提供了一个灵活的、可扩展的、跨平台的图表绘制解决方案,可以用于各种应用程序,如数据分析、科学计算、金融交易等。
15 1
|
8天前
Qt安装之后添加或移除组件(Qt Creator 10.0.1)
Qt安装之后添加或移除组件(Qt Creator 10.0.1)
16 2
|
12天前
|
关系型数据库 MySQL 测试技术
技术分享:深入C++时间操作函数的应用与实践
技术分享:深入C++时间操作函数的应用与实践
14 1
|
17天前
|
C++
C++的引用定义语法和应用
C++的引用定义语法和应用
|
27天前
|
算法 C++
C++中的结构应用:Josephus问题
C++中的结构应用:Josephus问题
13 1
|
1月前
|
C++ 存储 Java
C++ 引用和指针:内存地址、创建方法及应用解析
'markdown'C++ 中的引用是现有变量的别名,用 `&` 创建。例如:`string &meal = food;`。指针通过 `&` 获取变量内存地址,用 `*` 创建。指针变量存储地址,如 `string *ptr = &food;`。引用不可为空且不可变,指针可为空且可变,适用于动态内存和复杂数据结构。两者在函数参数传递和效率提升方面各有优势。 ```