C++ Qt開發:Tab與Tree元件實現分頁選單

lyshark發表於2023-12-16

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

1.1 TabWidget

QTabWidget 是 Qt 中的一個用於顯示多個頁面的小部件,其中每個頁面通常包含不同的內容。每個頁面與一個標籤相關聯,使用者可以透過點選標籤來切換不同的頁面。QTabWidget 是一個常見的使用者介面元素,用於組織和展示具有層次結構的資訊。

以下是關於 QTabWidget 的主要特點和用法:

主要特點

  1. 多頁顯示: QTabWidget 允許在同一視窗中顯示多個頁面,每個頁面由一個標籤頁表示。
  2. 標籤頁: 每個頁面都有一個與之相關聯的標籤,通常是一個文字標籤或包含圖示的標籤,用於顯示頁面的名稱或標識。
  3. 切換頁面: 使用者可以透過點選標籤頁來切換顯示不同的頁面,使得只有一個頁面處於可見狀態。
  4. 自定義標籤頁: QTabWidget 允許透過新增小部件(如按鈕、文字框等)作為標籤頁,以定製標籤頁的外觀和功能。

以下是 QTabWidget 類的一些常用方法的說明和概述,以表格形式列出:

方法 描述
QTabWidget(QWidget *parent = nullptr) 建構函式,建立一個 QTabWidget 物件。
addTab(QWidget *widget, const QString &label) QTabWidget 新增一個標籤頁,並關聯一個小部件。
insertTab(int index, QWidget *widget, const QString &label) 在指定位置插入一個標籤頁,並關聯一個小部件。
removeTab(int index) 移除指定位置的標籤頁。
clear() 移除所有的標籤頁。
setCurrentIndex(int index) 設定當前顯示的標籤頁的索引。
currentIndex() 獲取當前顯示的標籤頁的索引。
count() 獲取標籤頁的數量。
widget(int index) 獲取指定索引處的標籤頁關聯的小部件。
tabText(int index) 獲取指定索引處的標籤頁的文字。
setTabText(int index, const QString &text) 設定指定索引處的標籤頁的文字。
tabIcon(int index) 獲取指定索引處的標籤頁的圖示。
setTabIcon(int index, const QIcon &icon) 設定指定索引處的標籤頁的圖示。
tabBar() 返回 QTabBar 物件,允許對標籤欄進行更高階的操作。
tabBar()->setTabButton(int index, QTabBar::ButtonPosition position, QWidget *widget) 在指定位置新增一個小部件按鈕到標籤頁。
setTabEnabled(int index, bool enable) 啟用或禁用指定索引處的標籤頁。
isTabEnabled(int index) 檢查指定索引處的標籤頁是否啟用。
setTabToolTip(int index, const QString &tip) 設定指定索引處的標籤頁的工具提示。
tabToolTip(int index) 獲取指定索引處的標籤頁的工具提示。
setTabWhatsThis(int index, const QString &text) 設定指定索引處的標籤頁的 What's This 文字。
tabWhatsThis(int index) 獲取指定索引處的標籤頁的 What's This 文字。
currentChanged(int index) 當前標籤頁發生變化時發出的訊號,連線到槽函式以執行相應的操作。
tabCloseRequested(int index) 使用者請求關閉標籤頁時發出的訊號,連線到槽函式以執行相應的操作。

這些方法提供了對 QTabWidget 進行標籤頁管理、屬性設定以及與標籤頁互動的控制。你可以根據具體需求使用這些方法,定製 QTabWidget 的外觀和行為。

與其他通用元件不同,TabWidget 元件只能透過在頁面中新增,當需要增加新的子選單時,可以透過右鍵元件選中插入頁,在當前之後插入,這裡我們分別增加四個子夾,此處只需要增加不需要重新命名。

針對子夾的美化也很簡單,只需要呼叫setTab系列函式即可,需要注意的是,呼叫這些函式其中第一個引數均為子選擇夾的下標索引值,該索引值預設是從0開始計數的,完整程式碼如下所示;

MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    // 全域性配置tabWidget選項卡
    ui->tabWidget->setTabPosition(QTabWidget::North);       // 設定選項卡方位
    ui->tabWidget->setIconSize(QSize(50, 25));              // 設定圖示整體大小
    ui->tabWidget->setTabShape(QTabWidget::Triangular);     // 設定選項卡形狀
    ui->tabWidget->setMovable(true);                        // 設定選項卡是否可拖動
    ui->tabWidget->usesScrollButtons();                     // 選項卡滾動

    // 設定選項卡1
    ui->tabWidget->setTabText(0,QString("進位制轉換標籤"));           // 設定選項卡文字
    ui->tabWidget->setTabIcon(0,QIcon(":/image/about.ico"));      // 設定選項卡圖示
    ui->tabWidget->setTabToolTip(0,QString("SpinBox 與進位制轉換"));  // 設定滑鼠懸停提示

    // 設定選項卡2
    ui->tabWidget->setTabText(1,QString("顏色配置標籤"));          // 設定選項卡文字
    ui->tabWidget->setTabIcon(1,QIcon(":/image/file.ico"));      // 設定選項卡圖示
    ui->tabWidget->setTabToolTip(1,QString("滑塊條的使用"));       // 設定滑鼠懸停提示

    // 設定選項卡3
    ui->tabWidget->setTabText(2,QString("系統配置標籤"));          // 設定選項卡文字
    ui->tabWidget->setTabIcon(2,QIcon(":/image/lock.ico"));      // 設定選項卡圖示
    ui->tabWidget->setTabToolTip(2,QString("圓形元件與數碼錶"));    // 設定滑鼠懸停提示

    // 設定選項卡4
    ui->tabWidget->setTabText(3,QString("檔案配置標籤"));          // 設定選項卡文字
    ui->tabWidget->setTabIcon(3,QIcon(":/image/lock.ico"));      // 設定選項卡圖示
    ui->tabWidget->setTabToolTip(3,QString("檔案配置組合"));       // 設定滑鼠懸停提示
}

該元件常用於分頁操作,以讓應用程式可以在一個頁面中容納更多的子頁面,如下圖我們分別建立了四個選擇夾,並實現了分頁展示的效果;

1.2 TreeWidget

QTreeWidget 是 Qt 中的一個用於顯示樹形結構的小部件。它允許使用者透過展開和摺疊樹節點來檢視和管理層次化的資料。每個節點可以包含子節點,形成一個樹狀結構。QTreeWidget 繼承自 QTreeWidget,提供了更高階的樹狀結構顯示功能。

以下是關於 QTreeWidget 的主要特點和用法:

主要特點

  1. 樹形結構: QTreeWidget 支援顯示樹形結構,每個節點可以包含子節點,形成一個層次化的樹。
  2. 列顯示: 可以在每個節點下顯示多列資料,每列可以包含不同的資訊,這使得 QTreeWidget 可以用於顯示錶格型資料。
  3. 編輯節點: 使用者可以編輯節點的資料,允許動態修改樹的內容。
  4. 選擇和操作: 提供了豐富的選擇和操作功能,使用者可以透過鍵盤或滑鼠進行節點的選擇、展開和摺疊等操作。
  5. 訊號與槽: QTreeWidget 傳送各種訊號,如 itemClickeditemDoubleClicked 等,以便在使用者與樹互動時執行相應的操作。

以下是 QTreeWidget 類的一些常用方法的說明和概述,以表格形式列出:

方法 描述
QTreeWidget(QWidget *parent = nullptr) 建構函式,建立一個 QTreeWidget 物件。
addTopLevelItem(QTreeWidgetItem *item) 向樹中新增一個頂級項。
insertTopLevelItem(int index, QTreeWidgetItem *item) 在指定位置插入一個頂級項。
takeTopLevelItem(int index) 移除並返回指定位置的頂級項。
clear() 移除所有的項。
topLevelItemCount() 獲取頂級項的數量。
topLevelItem(int index) 獲取指定位置的頂級項。
invisibleRootItem() 獲取樹的不可見根項。
setCurrentItem(QTreeWidgetItem *item) 設定當前項。
currentItem() 獲取當前項。
setItemWidget(QTreeWidgetItem *item, int column, QWidget *widget) 在指定項和列上設定一個小部件。
itemWidget(QTreeWidgetItem *item, int column) 獲取指定項和列上的小部件。
editItem(QTreeWidgetItem *item, int column) 編輯指定項和列的資料。
closePersistentEditor(QTreeWidgetItem *item, int column) 關閉指定項和列上的持久編輯器。
collapseItem(QTreeWidgetItem *item) 摺疊指定項。
expandItem(QTreeWidgetItem *item) 展開指定項。
isItemExpanded(QTreeWidgetItem *item) 檢查指定項是否展開。
setItemExpanded(QTreeWidgetItem *item, bool expand) 設定指定項的展開狀態。
scrollToItem(QTreeWidgetItem *item, QAbstractItemView::ScrollHint hint = EnsureVisible) 滾動檢視以確保指定項可見。
setItemHidden(QTreeWidgetItem *item, bool hide) 設定指定項的隱藏狀態。
isItemHidden(QTreeWidgetItem *item) 檢查指定項是否隱藏。
setItemDisabled(QTreeWidgetItem *item, bool disable) 設定指定項的禁用狀態。
isItemDisabled(QTreeWidgetItem *item) 檢查指定項是否禁用。
setItemSelected(QTreeWidgetItem *item, bool select) 設定指定項的選擇狀態。
isItemSelected(QTreeWidgetItem *item) 檢查指定項是否被選擇。
itemAt(const QPoint &p) 返回在指定位置的項。
indexOfTopLevelItem(QTreeWidgetItem *item) 獲取指定頂級項的索引。
clearSelection() 清除所有選定的項。
sortItems(int column, Qt::SortOrder order = Qt::AscendingOrder) 根據指定列的資料對項進行排序。
headerItem() 獲取樹的標題項。
setHeaderItem(QTreeWidgetItem *item) 設定樹的標題項。
header() 獲取樹的標題。
setHeaderLabel(const QString &label) 設定樹的標題。
headerItem() 獲取樹的標題項。
setHeaderItem(QTreeWidgetItem *item) 設定樹的標題項。
header() 獲取樹的標題。
setHeaderLabel(const QString &label) 設定樹的標題。
setSortingEnabled(bool enable) 啟用或禁用樹的排序功能。
isSortingEnabled() 檢查樹的排序功能是否啟用。
sortColumn() 獲取當前排序的列。
sortOrder() 獲取當前排序的順序。
sortByColumn(int column, Qt::SortOrder order) 根據指定列的資料對項進行排序。
currentChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous) 當前項發生變化時發出的訊號,連線到槽函式以執行相應的操作。
itemClicked(QTreeWidgetItem *item, int column) 項被點選時發出的訊號,連線到槽函式以執行相應的操作。
itemDoubleClicked(QTreeWidgetItem *item, int column) 項被雙擊時發出的訊號,連線到槽函式以執行相應的操作。
itemPressed(QTreeWidgetItem *item, int column) 項被按下時發出的訊號,連線到槽函式以執行相應的操作。
itemActivated(QTreeWidgetItem *item, int column) 項被啟用時發出的訊號,連線到槽函式以執行相應的操作。
itemCollapsed(QTreeWidgetItem *item) 項被摺疊時發出的訊號,連線到槽函式以執行相應的操作。
itemExpanded(QTreeWidgetItem *item) 項被展開時發出的訊號,連線到槽函式以執行相應的操作。
itemChanged(QTreeWidgetItem *item, int column) 項的資料發生變化時發出的訊號,連線到槽函式以執行相應的操作。
itemSelectionChanged() 選定項發生變化時發出的訊號,連線到槽函式以執行相應的操作。

這些方法提供了對 QTreeWidget 進行樹節點管理、屬性設定以及與樹節點互動的控制。你可以根據具體需求使用這些方法,定製 QTreeWidget 的外觀和行為。

雖然TreeWidget元件可以實現多節點的增刪改查功能,但在一般的應用場景中基本上只使用一層結構即可解決大部分開發需求,TreeWidget元件通常可配合TabWidget元件實現類似於樹形選單欄的功能,當使用者點選選單欄中的選項時則會跳轉到不同的頁面上。

首先在Qt的UI編輯介面左側加入TreeWidget元件,右側加入TabWidget元件,將頁面中的TabWidget元件增加指定頁,整體頁面佈局如下所示;

要實現對頁面的美化只需要在程式碼中進行調整,在MainWindow::MainWindow主函式中我們對其中的兩個元件進行初始化操作,並透過setText設定標籤名,透過setIcon設定圖示組,最後透過expandAll執行重新整理到頁面,其核心程式碼如下所示;

#include <iostream>
#include <QStyleFactory>

MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    ui->treeWidget->clear();
    ui->treeWidget->setColumnCount(1);
    ui->treeWidget->setHeaderHidden(true);

    // 隱藏tabWidget頭部
    ui->tabWidget->tabBar()->hide();

    // 為treeWidget增加線條
    ui->treeWidget->setStyle(QStyleFactory::create("windows"));

    // ----------------------------------------------------------
    // 建立 [系統設定] 父節點
    // ----------------------------------------------------------
    QTreeWidgetItem *system_setup = new QTreeWidgetItem(ui->treeWidget,QStringList(QString("系統位置")));
    system_setup->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsAutoTristate);
    system_setup->setIcon(0,QIcon(":/image/lock.ico"));

    // 給父節點新增子節點
    QTreeWidgetItem *system_setup_child_node_1 = new QTreeWidgetItem(system_setup);
    system_setup_child_node_1->setText(0,"修改密碼");
    system_setup_child_node_1->setIcon(0,QIcon(":/image/about.ico"));

    QTreeWidgetItem *system_setup_child_node_2 = new QTreeWidgetItem(system_setup);
    system_setup_child_node_2->setText(0,"設定選單");
    system_setup_child_node_2->setIcon(0,QIcon(":/image/about.ico"));

    // ----------------------------------------------------------
    // 建立 [頁面佈局] 父節點
    // ----------------------------------------------------------
    QTreeWidgetItem *page_layout = new QTreeWidgetItem(ui->treeWidget,QStringList(QString("頁面佈局")));
    page_layout->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsAutoTristate);
    page_layout->setIcon(0,QIcon(":/image/lock.ico"));

    QTreeWidgetItem *page_layout_clild_1 = new QTreeWidgetItem(page_layout);
    page_layout_clild_1->setText(0,"頁面配置");
    page_layout_clild_1->setIcon(0,QIcon(":/image/about.ico"));

    QTreeWidgetItem *page_layout_clild_2 = new QTreeWidgetItem(page_layout);
    page_layout_clild_2->setText(0,"頁面引數");
    page_layout_clild_2->setIcon(0,QIcon(":/image/about.ico"));

    ui->treeWidget->expandAll();
}

當上述程式碼執行後我們可以得到一個經過美化後的頁面,但我們還需要將TreeWidgetTabWidget元件的頁碼進行繫結,當使用者點選TreeWidget元件時我們可以透過on_treeWidget_itemDoubleClicked槽函式獲取到點選的頁,透過在TreeWidget元件上右鍵並轉到槽,找到itemDoubleClicked被點選事件,當頁面被點選時則觸發跳轉,程式碼如下所示;

void MainWindow::on_treeWidget_itemDoubleClicked(QTreeWidgetItem *item, int column)
{
    QString str = item->text(column);

     if(str == "修改密碼")
     {
         ui->tabWidget->setCurrentIndex(0);
     }
     if(str == "設定選單")
     {
         ui->tabWidget->setCurrentIndex(1);
     }
     if(str == "頁面配置")
     {
         ui->tabWidget->setCurrentIndex(2);
     }
     if(str == "頁面引數")
     {
         ui->tabWidget->setCurrentIndex(3);
     }
}

執行這個程式,讀者可自行切換測試效果,當需要功能分頁時只需要分別開發不同頁面並放入到特定的TabWidget組中即可,如下圖所示;

相關文章