一、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