C++ Qt開發:MdiArea多窗體元件

lyshark發表於2023-12-19

Qt 是一個跨平臺C++圖形介面開發庫,利用Qt可以快速開發跨平臺窗體應用程式,在Qt中我們可以透過拖拽的方式將不同元件放到指定的位置,實現圖形化開發極大的方便了開發效率,本章將重點介紹MdiArea`元件的常用方法及靈活運用。

QMdiArea(Multiple Document Interface Area)是Qt中用於建立多文件介面的元件。它提供了一種在單個視窗中管理多個文件的方式,每個文件通常是一個子視窗(QMdiSubWindow)。該元件主要用於設計多文件介面應用程式,具備有多種窗體展示風格,實現了在父窗體中內嵌多種子窗體的功能,使開發者能夠輕鬆地建立支援多個文件的應用程式。

下面是一些常用的QMdiArea的方法,說明並概述成表格:

方法 說明
QMdiArea(QWidget *parent = nullptr) 建構函式,建立一個QMdiArea例項。
addSubWindow(QWidget *widget, Qt::WindowFlags flags = Qt::WindowFlags()) 將指定的QWidget新增為QMdiArea的子視窗。
cascadeSubWindows() 將所有子視窗進行層疊排列。
tileSubWindows() 平鋪排列所有子視窗。
closeAllSubWindows() 關閉所有子視窗。
setBackground(const QBrush &background) 設定QMdiArea的背景色或背景圖片。
setViewMode(QMdiArea::ViewMode mode) 設定子視窗排列模式,例如QMdiArea::SubWindowViewQMdiArea::TabbedView
setTabsClosable(bool closable) 設定子視窗標籤是否可關閉。
setTabsMovable(bool movable) 設定子視窗標籤是否可移動。
setTabShape(QTabWidget::TabShape shape) 設定子視窗標籤的形狀,例如QTabWidget::RoundedQTabWidget::Triangular
setDocumentMode(bool enabled) 設定是否以文件模式顯示子視窗標籤。
setTabPosition(QTabWidget::TabPosition position) 設定子視窗標籤的位置,例如QTabWidget::NorthQTabWidget::South
setActivationOrder(QMdiArea::ActivationOrder order) 設定子視窗的啟用順序,例如QMdiArea::StackingOrderQMdiArea::CreationOrder
setTabbedView(bool tabbed) 將QMdiArea設定為標籤檢視,即子視窗以標籤頁的形式顯示。
setOption(QMdiArea::AreaOption option, bool on = true) 設定QMdiArea的選項,例如QMdiArea::DontMaximizeSubWindowOnActivation
activeSubWindow() 返回當前啟用的子視窗,如果沒有啟用的子視窗則返回nullptr。
closeActiveSubWindow() 關閉當前啟用的子視窗。

這只是一些常用方法的概述,實際上QMdiArea提供了更多的方法和選項,以滿足不同應用場景的需求。開發者可以根據具體需求查閱官方文件獲取更詳細的資訊。

讀者在使用MDI元件時,需要在UI介面中增加mdiArea控制元件容器,之後所有窗體建立與操作都要在容器內進行,其次由於MDI窗體元件僅僅是一個畫布只具備限制視窗的作用,無法實現生成窗體,所以需要在專案中手動增加自定義Dialog對話方塊,並對該對話方塊進行一定的定製,首先繪製如下案例,其頂部是一個QToolBar元件,底部則是一個QMidArea元件,如下圖;

接著我們需要以此對上述選單繫結一個唯一的名稱及文字,這個過程可以透過程式碼實現,也可以透過圖形化配置,如下圖我們直接透過圖形化模式增加其功能;

1.1 初始化控制元件

如下程式碼,使用QMdiArea建立多文件介面的MainWindow類的建構函式和解構函式。

下面是一些關鍵點的概述:

  1. QMdiArea設定為中央視窗:
    • this->setCentralWidget(ui->mdiArea);QMdiArea設定為主視窗的中央視窗,表示主要的工作區域將由QMdiArea管理。
  2. 主視窗最大化顯示(註釋部分):
    • this->setWindowState(Qt::WindowMaximized); 這是一行註釋掉的程式碼,表示將主視窗設定為最大化顯示。你可以根據需要取消註釋,以便在啟動應用程式時視窗最大化。
  3. 工具欄設定:
    • ui->mainToolBar->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); 設定工具欄按鈕的顯示風格為圖示下方顯示文字。這種設定在工具欄上同時顯示圖示和文字,提供了更直觀的使用者介面。
  4. 子視窗模式設定:
    • ui->mdiArea->setViewMode(QMdiArea::SubWindowView);QMdiArea的檢視模式設定為子視窗模式。在子視窗模式下,QMdiArea管理並顯示各個子視窗,允許使用者同時檢視和編輯多個文件。
  5. 解構函式:
    • 解構函式中執行了 delete ui;,確保在物件銷燬時釋放與ui相關的資源,避免記憶體洩漏。

這段程式碼片段展示了一個使用QMdiArea建立多文件介面的主視窗類的基本結構和初始化設定。在這個視窗中,使用者可以開啟和管理多個子視窗,每個子視窗可以包含一個獨立的文件。

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

程式開啟後可以看到如下圖所示的介面;

1.2 新建與關閉窗體

新建窗體時只需要呼叫new Dialog建立新的窗體,並透過addSubWindow()將新的窗體指標加入到元件內即可,當關閉時可以直接透過呼叫closeAllSubWindows()來實現,如下程式碼則是建立與關閉的實現。

// 新建窗體
void MainWindow::on_actionOpen_triggered()
{
    // 建立Dialog窗體
    Dialog *formDoc = new Dialog(this);

    // 文件視窗新增到MDI
    ui->mdiArea->addSubWindow(formDoc);

    // 在單獨的視窗中顯示
    formDoc->show();
}

// 關閉全部
void MainWindow::on_actionClose_triggered()
{
    // 關閉所有子視窗
    ui->mdiArea->closeAllSubWindows();
}

執行後可以點選開啟窗體建立,這個建立是無限制的,如下圖;

1.3 轉換窗體模式

針對模式的轉換此處提供了三種模式,分別是MDI模式、級聯模式及平鋪模式,三種模式的實現只需要呼叫不同的介面即可實現,程式碼如下所示;

// 轉為MDI模式
void MainWindow::on_actionMID_triggered(bool checked)
{
    // Tab多頁顯示模式
    if (checked)
    {
        // Tab多頁顯示模式
        ui->mdiArea->setViewMode(QMdiArea::TabbedView);
        // 頁面可關閉
        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);
    }
}

// 恢復預設模式
void MainWindow::on_actionWindow_triggered()
{
    ui->mdiArea->setViewMode(QMdiArea::SubWindowView);
    ui->actionLine->setEnabled(true);
    ui->actionMID->setEnabled(true);
    ui->actionTile->setEnabled(true);
}

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

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

子視窗模式(QMdiArea::SubWindowView)

  • 這是多文件介面的預設模式,允許使用者在主視窗內同時開啟多個子視窗,每個子視窗可以包含一個獨立的文件或檢視。
  • 子視窗可以重疊、平鋪、級聯等方式排列。

標籤頁多頁顯示模式(QMdiArea::TabbedView)

  • 在這種模式下,子視窗以標籤頁的形式顯示在主視窗的頂部,使用者可以透過點選標籤頁來切換不同的子視窗。
  • 提供了標籤頁的關閉按鈕,允許使用者關閉特定的標籤頁。

級聯模式和平鋪模式

  • 這兩種模式是在標籤頁多頁顯示模式下的兩種特定排列方式。
  • 級聯模式(Cascade): 子視窗以重疊的方式顯示,類似級聯排列的效果,方便使用者檢視和操作每個子視窗。

  • 平鋪模式(Tile): 子視窗以平鋪的方式顯示,使它們在主視窗中均勻分佈,方便使用者同時瀏覽多個子視窗內容。

這些模式提供了不同的使用者體驗,使使用者能夠根據實際需求選擇最適合他們工作流程的視窗排列方式。使用者可以根據應用程式的性質和自己的使用偏好在這些模式之間切換。

完整案例下載

相關文章