• Qt 的MDI 多文档窗口


    一、MDI简介

    MDI就是多文档界面(Multi-document Interface,MDI)应用程序

    MDI就是在主窗口里创建多个同类型的MDI子窗口,这些MDI子窗口在主窗口里显示,并共享主窗口上工具栏和菜单等操作功能,主窗口上的操作都针对当前活动的MDI子窗口进行

    二、QMdiArea组件

    设计MDI应用程序需要在主窗口工作区放置一个QMdiArea作为MDI子窗体的容器

    所以我们需要事先创建窗体类对象,然后将窗口类通过addSubWindow函数添加到MDIArea组件中,然后再调用窗口类的show函数显示窗体

    image.png

    三、MDI的一些注意事项

    • 当在主窗口中关闭一个MDI子窗口时,这个MDI窗口对象都会删除。也可以使用setAttribute(Qt::WA_DeleteOnClose);函数显示设置在关闭MDI时删除窗口对象

    四、QMDIArea组件的相关函数

    addSubWindow函数

    • 此函数将一个窗口类添加到MDIArea中,然后调用窗口类的show函数显示在MDIArea中

    image.png

    image.png

    activeSubWindow、widget函数

    该函数返回当前选中的活动的子窗口,返回的是QMdiSubWindow指针对象

    这样我们就可以通过activeSubWindow函数返回的QMdiSubWindow指针对象,间接通过widget函数得到该窗口的对象(但是需要强制类型转换)

    QMdiSubWindow *QMdiArea::activeSubWindow() const

    C++
    //头文件:#include <QMdiSubWindow>
    QWidget *QMdiSubWindow::widget() const

    image.png

    subWindowList函数

    • 此函数返回MDIArea组件中的窗口类列表

    • 因此我们可以通过该函数再调用count函数获取当前MDIArea中的窗体数量

    C++
    QList<QMdiSubWindow *> QMdiArea::subWindowList(WindowOrder order = CreationOrder) const

    image.png

    loadFormFile函数

    • 当某个窗体添加到MDIArea中之后,就可以通过此函数加载一个文件的内容

    • 参数为QString对象,该对象是通过QFileDialog::getOpenFileName函数打开的

    image.png

    closeAllSubWindows函数

    • 通过此函数关闭MDIArea组件中的所有窗口

    void QMdiArea::closeAllSubWindows()

    image.png

    tabsClosable()、setTabsClosable函数

    • tabsClosable:返回当前的MDIArea中的某个窗口是否可以关闭

    • setTabsClosable:设置当前的MDIArea中的某个窗口是否可以关闭

    C++
    bool tabsClosable() const
    void setTabsClosable(bool closable)

    viewMode、setViewMode函数

    • viewMode:返回当前MDIArea中某个窗口的显示模式

    • setViewMode:设置当前MDIArea中某个窗口的显示模式

    C++
    ViewMode viewMode() const
    void setViewMode(ViewMode mode)
    C++
    ViewMode 类型如下:
    QMdiArea::TabbedView     //Tab多页显示模式
    QMdiArea::SubWindowView //子窗口模式

    窗口默认显示为“子窗口模式”显示,Tab多页显示模式如下图所示:

    image.png

    cascadeSubWindows、tileSubWindows函数

    • cascadeSubWindows:窗口级联模式展开显示

    • tileSubWindows:窗口平铺模式展开显示

    C++
    void QMdiArea::cascadeSubWindows()
    void QMdiArea::tileSubWindows()

    image.png

    textCut、setEditFont等函数

    • 当我们将窗口添加到MDIArea中之后,就可以调用这些函数来对窗口的字体进行格式化设置、剪切、复制

    image.png

    五、QMDIArea组件的信号函数

    subWindowActivated信号函数

    • 当前活动窗口切换时触发此信号函数,利用此信号可以在活动窗口切换时进行一些处理

    subWindowActivated(QMdiSubWindow *arg1)

    演示案例

    image.png

    一、文档类窗体的设计

    • 这个窗体类是用来放在主窗体的MDIArea组件中的

    ①窗体创建与设计

    • 类中只放置一个QPlainTextEdit组件,并以水平布局填充整个窗口

    image.png

    image.png

    image.png

    image.png

    image.png

    ②类的初始化

    C++
    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;
    };

    ③相关函数的定义

    C++
    //构造函数
    QFormDoc::QFormDoc(QWidget *parent) :
        QWidget(parent),
        ui(new Ui::QFormDoc)
    {
        ui->setupUi(this);
        this->setWindowTitle("New Doc");         //窗口标题 
        this->setAttribute(Qt::WA_DeleteOnClose);//关闭时自动删除(备注:不论是否设置此项,MDI在关闭时,都会删除窗口对象)
    }
    C++
    //析构函数
    QFormDoc::~QFormDoc()
    {
        QMessageBox::information(this,QStringLiteral("信息"),
                 QStringLiteral("文档窗口被释放"));//窗口关闭之后提示
        delete ui;
    }
    C++
    //打开文件,并将文件内容读取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;
        }
    }
    C++
    //返回当前文件名称
    QString QFormDoc::currentFileName()
    {
    return mCurrentFile;
    }
    C++
    //判断当前文件是否打开,打开返回true
    bool QFormDoc::isFileOpened()
    {
    return mFileOpened;
    }
    C++
    //设置plainTextEdit的梯子
    void QFormDoc::setEditFont()
    {
        QFont font=ui->plainTextEdit->font();
        bool ok;
        font=QFontDialog::getFont(&ok,font); //打开字体设置窗体
     
        ui->plainTextEdit->setFont(font);
    }
    C++
    //对文档的剪切、复制、黏贴
    void QFormDoc::textCut()
    {
        ui->plainTextEdit->cut();
    }
     
    void QFormDoc::textCopy()
    {
        ui->plainTextEdit->copy();
    }
     
    void QFormDoc::textPaste()
    {
        ui->plainTextEdit->paste();
    }

    二、主窗体设计

    ①主窗体界面设计

    • 主窗体中是一个MDI Area组件

    image.png

    因为要在主窗口调用刚才自己设计的MDI窗体类QFormDoc,所以加入下面的头文件

    image.png

    ②Action设计

    • 添加了以下的Action,作为主窗体的工具栏使用

    image.png

    ③构造函数

    C++
    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);
    }

    ④新建文档按钮的触发函数

    image.png

    点击此按钮,在MDIArea中创建一个新的窗体

    C++
    void MainWindow::on_actDoc_New_triggered()
    {
        QFormDoc *formDoc=new QFormDoc(this); //创建文档窗口对象
        ui->mdiArea->addSubWindow(formDoc); //将文档窗口添加到MDI中
        formDoc->show(); //显示MDI窗体
    }

    ⑤打开文档按钮的触发函数

    image.png

    点击此按钮,选择一个文档,并将文档的内容显示到MDIArea的窗体中

    C++
    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);
    }

    ⑥关闭全部按钮的触发函数

    image.png

    点击此按钮,关闭MDI中所有窗体

    C++
    void MainWindow::on_actCloseAll_triggered()
    {
    ui->mdiArea->closeAllSubWindows();//关闭全部子窗口
    }

    ⑦MDI模式按钮的触发函数

    image.png

    C++
    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);
        }
    }

    ⑧级联展开、平铺展开按钮触发函数

    image.png

    C++
    //窗体级联显示
    void MainWindow::on_actCascade_triggered()
    {
        ui->mdiArea->cascadeSubWindows();
    }
     
    //窗体平铺显示
    void MainWindow::on_actTile_triggered()
    {
        ui->mdiArea->tileSubWindows();
    }

    image.png

    级联展开

     

    image.png

    平铺展开

     

    ⑨其他按钮触发函数

    image.png

    C++
    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信号函数

    • 当前活动窗口切换时产生触发此信号函数,利用该信号函数可以在活动窗口切换时进行一些处理

    C++
    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
  • 相关阅读:
    Computability 2: Gödel Number
    Computability 1: Computational Models
    Axiomatic Set Theory
    External Sorting Model
    Minimum Spanning Tree
    All-Pairs Shortest Paths
    Python 泰坦尼克生存率预测(修改)
    Python 分析Kaggle_Titanic案例
    Python 北京二手房成交数据分析过程
    数据挖掘主要解决的四类问题以及常用到的算法
  • 原文地址:https://www.cnblogs.com/bruce1992/p/14489701.html
Copyright © 2020-2023  润新知