C++ Qt开发:TreeWidget 树形选择组件
Qt 是一個跨平臺C++圖形界面開發(fā)庫,利用Qt可以快速開發(fā)跨平臺窗體應用程序,在Qt中我們可以通過拖拽的方式將不同組件放到指定的位置,實現(xiàn)圖形化開發(fā)極大的方便了開發(fā)效率,本章將重點介紹TreeWidget樹形選擇組件的常用方法及靈活運用。
QTreeWidget 是 Qt 中的樹形控件組件,用于顯示樹形結(jié)構(gòu)的數(shù)據(jù)。它繼承自 QTreeView 和 QTreeWidget,提供了一個方便的方式來展示和編輯包含層次結(jié)構(gòu)數(shù)據(jù)的項目。
以下是 QTreeWidget 類的一些常用方法,說明和概述:
| 方法 | 描述 |
|---|---|
addTopLevelItem(QTreeWidgetItem *item) |
向樹中添加一個*項目。 |
addTopLevelItems(const QList<QTreeWidgetItem *> &items) |
向樹中添加多個*項目。 |
clear() |
清除樹中的所有項目。 |
currentItem() |
返回當前選擇的項目。 |
currentIndex() |
返回當前選擇的項目的模型索引。 |
editItem(QTreeWidgetItem *item, int column) |
進入編輯模式以編輯給定項目的指定列。 |
headerItem() |
返回樹的標題項目,該項目可用于設置標題標簽。 |
invisibleRootItem() |
返回樹的不可見根項目。 |
itemAbove(QTreeWidgetItem *item) |
返回給定項目的上面一個項目。 |
itemBelow(QTreeWidgetItem *item) |
返回給定項目的下面一個項目。 |
setCurrentItem(QTreeWidgetItem *item) |
設置當前選擇的項目。 |
topLevelItem(int index) |
返回樹中給定索引的*項目。 |
topLevelItemCount() |
返回樹的*項目的數(shù)量。 |
insertTopLevelItem(int index, QTreeWidgetItem *item) |
在給定索引處插入一個*項目。 |
insertTopLevelItems(int index, const QList<QTreeWidgetItem *> &items) |
在給定索引處插入多個*項目。 |
takeTopLevelItem(int index) |
從樹中移除給定索引處的*項目,并返回該項目的指針。 |
scrollToItem(QTreeWidgetItem *item, QAbstractItemView::ScrollHint hint = EnsureVisible) |
滾動樹以確保給定項目可見。 |
sortItems(int column, Qt::SortOrder order = Qt::AscendingOrder) |
對樹中的項目進行排序。 |
findItems(const QString &text, Qt::MatchFlags flags, int column = 0) |
查找樹中包含指定文本的項目。 |
這只是 QTreeWidget 類的一小部分方法。你可以查閱官方文檔以獲取完整的方法列表,以及這些方法的詳細說明。
首先我們來繪制一下UI界面,由于該節(jié)點同時具備編輯功能所以實現(xiàn)起來要稍微復雜一些,我們分別在最左側(cè)放置一個TreeWidget組件,在中間放置不同的PushButton組件,最后是一個plainTextEdit組件用來接收反饋,如下圖所示;
1.1 初始化組件
如下代碼是在 Qt 中使用 QTreeWidget 初始化一個樹形結(jié)構(gòu),其中包含了朋友、同學和陌生人等不同分類的節(jié)點。
以下是概述:
-
初始化
QTreeWidget: 設置QTreeWidget的一些基本屬性,包括列數(shù)、標題的隱藏等。 -
創(chuàng)建父節(jié)點 "朋友": 使用
QTreeWidgetItem創(chuàng)建一個朋友節(jié)點,并設置圖標、選擇狀態(tài)等屬性。然后添加兩個子節(jié)點 "老張" 和 "老王",分別設置圖標和選擇狀態(tài)。 - 創(chuàng)建父節(jié)點 "同學": 類似地,創(chuàng)建一個同學節(jié)點,并添加兩個子節(jié)點 "張三" 和 "李四",設置相應的圖標和選擇狀態(tài)。
-
創(chuàng)建 "陌生人" 節(jié)點: 使用
QTreeWidgetItem直接創(chuàng)建一個陌生人節(jié)點,并設置文本和圖標。 -
將節(jié)點添加到
QTreeWidget中: 使用addTopLevelItem將 "同學" 和 "陌生人" 節(jié)點添加到QTreeWidget的*。 -
展開所有節(jié)點: 使用
expandAll展開所有節(jié)點,使其在初始化時可見。 -
設置
QTreeWidget的大小: 使用resize設置QTreeWidget的大小。
這段代碼的主要功能是創(chuàng)建一個包含不同分類和子節(jié)點的樹形結(jié)構(gòu),每個節(jié)點可以有不同的圖標、文本和選擇狀態(tài)。在展示的樹形結(jié)構(gòu)中,朋友和同學節(jié)點有子節(jié)點,而陌生人節(jié)點沒有子節(jié)點。這個示例展示了 QTreeWidget 用于創(chuàng)建層次結(jié)構(gòu)的基本用法。
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->treeWidget->clear();
// ----------------------------------------------
// 初始化TreeWidget組件
// ----------------------------------------------
// 設置QTreeWidget的列數(shù)
ui->treeWidget->setColumnCount(1);
// 設置QTreeWidget標題隱藏
ui->treeWidget->setHeaderHidden(true);
// ----------------------------------------------
// 創(chuàng)建QTreeWidget的朋友節(jié)點 此時的父節(jié)點是TreeWidget
// ----------------------------------------------
QTreeWidgetItem *Friend = new QTreeWidgetItem(ui->treeWidget,QStringList(QString("朋友")));
Friend->setIcon(0,QIcon(":/image/4.ico"));
Friend->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable
| Qt::ItemIsEnabled | Qt::ItemIsAutoTristate);
Friend->setCheckState(0,Qt::Checked);
// 給Friend添加一個子節(jié)點frd
QTreeWidgetItem *frd = new QTreeWidgetItem(Friend);
frd->setText(0,"老張");
frd->setIcon(0,QIcon(tr(":/image/1.ico")));
frd->setCheckState(0,Qt::Checked);
// 繼續(xù)給Friend添加一個子節(jié)點frs
QTreeWidgetItem *frs = new QTreeWidgetItem(Friend);
frs->setText(0,"老王");
frs->setIcon(0,QIcon(tr(":/image/1.ico")));
frs->setCheckState(0,Qt::Unchecked);
// ----------------------------------------------
// 繼續(xù)創(chuàng)建名叫同學節(jié)點 父節(jié)點同樣是TreeWidget
// ----------------------------------------------
QTreeWidgetItem * ClassMate = new QTreeWidgetItem(ui->treeWidget,QStringList(QString("同學")));
ClassMate->setIcon(0,QIcon(":/image/5.ico"));
ClassMate->setCheckState(0,Qt::Checked);
// Fly是ClassMate的子節(jié)點
QTreeWidgetItem *Fly = new QTreeWidgetItem(QStringList(QString("張三")));
Fly->setIcon(0,QIcon(tr(":/image/2.ico")));
// 創(chuàng)建子節(jié)點的另一種方法
ClassMate->addChild(Fly);
Fly->setCheckState(0,Qt::Checked);
// 繼續(xù)創(chuàng)建子節(jié)點Fls
QTreeWidgetItem *Fls = new QTreeWidgetItem(QStringList(QString("李四")));
Fls->setIcon(0,QIcon(tr(":/image/2.ico")));
ClassMate->addChild(Fls);
Fls->setCheckState(0,Qt::Checked); // 設置為選中
// ----------------------------------------------
// 創(chuàng)建陌生人節(jié)點
// ----------------------------------------------
QTreeWidgetItem *Strange = new QTreeWidgetItem(true);
Strange->setText(0,"陌生人");
Strange->setIcon(0,QIcon(":/image/6.ico"));
ui->treeWidget->addTopLevelItem(ClassMate);
ui->treeWidget->addTopLevelItem(Strange);
// 展開QTreeWidget的所有節(jié)點
ui->treeWidget->expandAll();
ui->treeWidget->resize(271,401);
}
代碼運行后可動態(tài)對左側(cè)組件進行初始化,并增加應有的父節(jié)點與子節(jié)點,如下圖;
1.2 添加根節(jié)點
如下槽函數(shù),其核心功能是在 QTreeWidget 中添加一個新的*父節(jié)點,并在 QPlainTextEdit 中添加一行文本記錄。
以下是概述:
-
獲取節(jié)點文本: 使用
QString NodeText = "新的父節(jié)點";設置新父節(jié)點的文本。 -
創(chuàng)建新的
QTreeWidgetItem: 使用QTreeWidgetItem的構(gòu)造函數(shù)創(chuàng)建一個新的*父節(jié)點,并設置其文本和圖標。 -
添加節(jié)點到
QTreeWidget中: 使用ui->treeWidget->addTopLevelItem(item);將新的*父節(jié)點添加到QTreeWidget中。 -
記錄操作到
QPlainTextEdit中: 使用ui->plainTextEdit->appendPlainText("添加新的父節(jié)點");將一行文本記錄添加到QPlainTextEdit中,用于記錄操作。
這段代碼的作用是在點擊按鈕時,在 QTreeWidget 中添加一個新的*父節(jié)點,并在 QPlainTextEdit 中記錄這一操作。這樣可以用于在界面上動態(tài)添加樹節(jié)點,并記錄相關(guān)的操作信息。
void MainWindow::on_pushButton_add_clicked()
{
QString NodeText = "新的父節(jié)點";
QTreeWidgetItem *item = new QTreeWidgetItem(true);
item->setText(0,NodeText);
item->setIcon(0,QIcon(":/image/7.ico"));
ui->treeWidget->addTopLevelItem(item);
ui->plainTextEdit->appendPlainText("添加新的父節(jié)點");
}
運行后通過點擊添加根節(jié)點按鈕,每次則可以生成一個根,如下圖;
1.3 添加子節(jié)點
如下槽函數(shù),其核心功能是在 QTreeWidget 中添加新的子節(jié)點,并在 QPlainTextEdit 中添加一行文本記錄。
以下是概述:
-
獲取當前選擇的節(jié)點: 使用
QTreeWidgetItem * item= ui->treeWidget->currentItem();獲取當前在QTreeWidget中選擇的節(jié)點。 -
判斷是否有選擇的節(jié)點: 使用
if(item!=NULL)條件判斷,如果存在選擇的節(jié)點,則調(diào)用AddTreeNode函數(shù)添加子節(jié)點;否則,調(diào)用AddTreeRoot函數(shù)添加新的根節(jié)點。 -
添加子節(jié)點或新的根節(jié)點:
- 如果存在選擇的節(jié)點,調(diào)用
AddTreeNode(item,"新子節(jié)點","新子節(jié)點");添加一個新的子節(jié)點,其文本和圖標分別為 "新子節(jié)點"。 - 如果沒有選擇的節(jié)點,調(diào)用
AddTreeRoot("新子節(jié)點","新子節(jié)點");添加一個新的根節(jié)點,其文本和圖標同樣為 "新子節(jié)點"。
- 如果存在選擇的節(jié)點,調(diào)用
-
記錄操作到
QPlainTextEdit中: 使用ui->plainTextEdit->appendPlainText("添加新的子節(jié)點");將一行文本記錄添加到QPlainTextEdit中,用于記錄操作。
這段代碼的作用是在點擊按鈕時,根據(jù)用戶當前選擇的節(jié)點狀態(tài),在 QTreeWidget 中添加新的子節(jié)點或新的根節(jié)點,并記錄這一操作到 QPlainTextEdit 中。
QTreeWidgetItem * MainWindow::AddTreeRoot(QString name,QString desc)
{
QTreeWidgetItem * item=new QTreeWidgetItem(QStringList()<<name<<desc);
ui->treeWidget->addTopLevelItem(item);
return item;
}
QTreeWidgetItem * MainWindow::AddTreeNode(QTreeWidgetItem *parent,QString name,QString desc)
{
QTreeWidgetItem * item=new QTreeWidgetItem(QStringList()<<name<<desc);
parent->addChild(item);
return item;
}
void MainWindow::on_pushButton_addsubnode_clicked()
{
QTreeWidgetItem * item= ui->treeWidget->currentItem();
if(item!=NULL)
AddTreeNode(item,"新子節(jié)點","新子節(jié)點");
else
AddTreeRoot("新子節(jié)點","新子節(jié)點");
ui->plainTextEdit->appendPlainText("添加新的子節(jié)點");
}
子節(jié)點的添加依賴于封裝好的兩個AddTreeNode函數(shù),通過調(diào)用后則可以在父節(jié)點上添加子節(jié)點,如下圖;
1.4 修改選中節(jié)點
如下槽函數(shù),其核心功能是修改 QTreeWidget 中當前選中節(jié)點的文本和圖標,并在 QPlainTextEdit 中添加一行文本記錄。
以下是概述:
-
獲取當前選中的節(jié)點: 使用
QTreeWidgetItem *currentItem = ui->treeWidget->currentItem();獲取當前在QTreeWidget中選擇的節(jié)點。 -
判斷是否存在選擇的節(jié)點: 使用
if(currentItem == NULL)條件判斷,如果沒有選擇的節(jié)點,則直接返回。 -
修改選中節(jié)點的文本和圖標: 使用
for循環(huán)遍歷節(jié)點的所有列,通過setText修改每一列的文本為 "Modify" 加上列索引的字符串,通過setIcon修改每一列的圖標為特定的圖標。 -
記錄操作到
QPlainTextEdit中: 使用ui->plainTextEdit->appendPlainText("修改節(jié)點名");將一行文本記錄添加到QPlainTextEdit中,用于記錄操作。
這段代碼的作用是在點擊按鈕時,修改 QTreeWidget 中當前選中節(jié)點的文本和圖標,同時在 QPlainTextEdit 中記錄這一修改操作。
void MainWindow::on_pushButton_modifynode_clicked()
{
// 得到當前節(jié)點
QTreeWidgetItem *currentItem = ui->treeWidget->currentItem();
if(currentItem == NULL)
return;
// 修改選中項
for(int x=0;x<currentItem->columnCount();x++)
{
currentItem->setText(x,tr("Modify") + QString::number(x));
currentItem->setIcon(x,QIcon(":/image/1.ico"));
}
ui->plainTextEdit->appendPlainText("修改節(jié)點名");
}
修改節(jié)點的執(zhí)行效果如下圖,當點擊修改選中節(jié)點后則將自動替換節(jié)點名和圖標信息。
1.5 刪除選中節(jié)點
如下槽函數(shù),其核心功能是刪除 QTreeWidget 中當前選中節(jié)點,并在 QPlainTextEdit 中添加一行文本記錄。
以下是概述:
-
獲取當前選中的節(jié)點: 使用
QTreeWidgetItem *currentItem = ui->treeWidget->currentItem();獲取當前在QTreeWidget中選擇的節(jié)點。 -
判斷是否存在選擇的節(jié)點: 使用
if(currentItem == NULL)條件判斷,如果沒有選擇的節(jié)點,則直接返回。 -
判斷是否為*父節(jié)點: 使用
if(currentItem->parent() == NULL)條件判斷,如果當前節(jié)點沒有父節(jié)點(即為*父節(jié)點),則使用ui->treeWidget->takeTopLevelItem刪除該節(jié)點。 -
如果有父節(jié)點,使用父節(jié)點的
takeChild刪除子節(jié)點: 使用delete currentItem->parent()->takeChild(ui->treeWidget->currentIndex().row());刪除當前節(jié)點。這種情況下,要使用父節(jié)點的takeChild方法,因為直接刪除會導致父節(jié)點無法正確管理子節(jié)點。 -
記錄操作到
QPlainTextEdit中: 使用ui->plainTextEdit->appendPlainText("刪除一個節(jié)點");將一行文本記錄添加到QPlainTextEdit中,用于記錄操作。
這段代碼的作用是在點擊按鈕時,刪除 QTreeWidget 中當前選中的節(jié)點,并記錄這一刪除操作到 QPlainTextEdit 中。
void MainWindow::on_pushButton_delnode_clicked()
{
QTreeWidgetItem *currentItem = ui->treeWidget->currentItem();
if(currentItem == NULL)
return;
// 如果沒有父節(jié)點則直接刪除
if(currentItem->parent() == NULL)
{
delete ui->treeWidget->takeTopLevelItem(ui->treeWidget->currentIndex().row());
std::cout << ui->treeWidget->currentIndex().row() << std::endl;
}
else
{
// 如果有父節(jié)點就要用父節(jié)點的takeChild刪除節(jié)點
delete currentItem->parent()->takeChild(ui->treeWidget->currentIndex().row());
}
ui->plainTextEdit->appendPlainText("刪除一個節(jié)點");
}
刪除節(jié)點有兩種情況,如果只有父節(jié)點那么可以直接刪除,如果有子節(jié)點則那就要一并刪除,如下圖;
1.6 枚舉全部節(jié)點
如下槽函數(shù),其核心功能是遍歷 QTreeWidget 中的所有節(jié)點,并輸出每個節(jié)點的文本。
以下是概述:
-
獲取全部的根節(jié)點數(shù)量: 使用
int size = ui->treeWidget->topLevelItemCount();獲取*父節(jié)點的數(shù)量。 -
遍歷所有根節(jié)點: 使用
for循環(huán)遍歷每一個根節(jié)點,通過ui->treeWidget->topLevelItem(x)獲取當前的根節(jié)點。 -
輸出所有根節(jié)點: 使用
child->text(0).toStdString().data()輸出當前根節(jié)點的文本信息,并將其輸出到標準輸出流。 -
遍歷根節(jié)點下的子節(jié)點: 使用內(nèi)層
for循環(huán)遍歷當前根節(jié)點下的所有子節(jié)點,通過child->child(y)獲取子節(jié)點。 -
輸出子節(jié)點: 使用
grandson->text(0).toStdString().data()輸出當前子節(jié)點的文本信息,并將其輸出到標準輸出流。 -
記錄操作到
QPlainTextEdit中: 使用ui->plainTextEdit->appendPlainText("枚舉所有節(jié)點");將一行文本記錄添加到QPlainTextEdit中,用于記錄操作。
這段代碼的作用是在點擊按鈕時,遍歷 QTreeWidget 中的所有節(jié)點,輸出每個節(jié)點的文本信息,并將信息記錄到 QPlainTextEdit 中。
void MainWindow::on_pushButton_enumnode_clicked()
{
// 獲取到全部的根節(jié)點數(shù)量
int size = ui->treeWidget->topLevelItemCount();
QTreeWidgetItem *child;
for(int x=0;x<size;x++)
{
// 輸出所有父節(jié)點
child = ui->treeWidget->topLevelItem(x);
std::cout << "all root = "<< child->text(0).toStdString().data() << std::endl;
// 得到所有子節(jié)點計數(shù)
int childCount = child->childCount();
// std::cout << "all child count = " << childCount << std::endl;
// 輸出根節(jié)點下面的子節(jié)點
for(int y=0;y<childCount;++y)
{
QTreeWidgetItem *grandson = child->child(y);
std::cout << "--> sub child = "<< grandson->text(0).toStdString().data() << std::endl;
ui->plainTextEdit->appendPlainText(grandson->text(0).toStdString().data());
}
}
ui->plainTextEdit->appendPlainText("枚舉所有節(jié)點");
}
枚舉所有節(jié)點會將父節(jié)點與子節(jié)點一并輸出,如下圖;
1.7 枚舉選中節(jié)點
如下槽函數(shù),其核心功能是遍歷 QTreeWidget 中的所有節(jié)點,并輸出每個選中節(jié)點的文本信息。
以下是概述:
-
獲取全部的根節(jié)點數(shù)量: 使用
int size = ui->treeWidget->topLevelItemCount();獲取*父節(jié)點的數(shù)量。 -
遍歷所有根節(jié)點: 使用
for循環(huán)遍歷每一個根節(jié)點,通過ui->treeWidget->topLevelItem(x)獲取當前的根節(jié)點。 -
遍歷根節(jié)點下的子節(jié)點: 使用內(nèi)層
for循環(huán)遍歷當前根節(jié)點下的所有子節(jié)點,通過child->child(y)獲取子節(jié)點。 -
判斷是否選中: 使用
if(Qt::Checked == grandson->checkState(0))判斷當前子節(jié)點是否被選中。 - 輸出選中節(jié)點信息: 如果子節(jié)點被選中,輸出當前根節(jié)點與子節(jié)點的文本信息,并將信息輸出到標準輸出流。
-
記錄操作到
QPlainTextEdit中: 使用ui->plainTextEdit->appendPlainText("枚舉所有選中節(jié)點");將一行文本記錄添加到QPlainTextEdit中,用于記錄操作。
這段代碼的作用是在點擊按鈕時,遍歷 QTreeWidget 中的所有節(jié)點,輸出每個被選中節(jié)點的文本信息,并將信息記錄到 QPlainTextEdit 中。
void MainWindow::on_pushButton_enumselectnode_clicked()
{
// 獲取到全部的根節(jié)點數(shù)量
int size = ui->treeWidget->topLevelItemCount();
QTreeWidgetItem *child;
for(int x=0;x<size;x++)
{
// 輸出所有父節(jié)點
child = ui->treeWidget->topLevelItem(x);
// 得到所有子節(jié)點計數(shù)
int childCount = child->childCount();
// 輸出根節(jié)點下面的子節(jié)點
for(int y=0;y<childCount;++y)
{
QTreeWidgetItem *grandson = child->child(y);
// 判斷是否選中,如果選中輸出父節(jié)點與子節(jié)點
if(Qt::Checked == grandson->checkState(0))
{
std::cout << "root -> " << child->text(0).toStdString().data()
<< "--> sub child = "<< grandson->text(0).toStdString().data() << std::endl;
ui->plainTextEdit->appendPlainText(child->text(0).toStdString().data());
ui->plainTextEdit->appendPlainText(grandson->text(0).toStdString().data());
}
}
}
ui->plainTextEdit->appendPlainText("枚舉所有選中節(jié)點");
}
枚舉所有選中的節(jié)點,此處需要打上對勾才會生效,如下圖;
1.8 獲取節(jié)點父節(jié)點
如下槽函數(shù),其核心功能是獲取當前選中節(jié)點的父節(jié)點(如果存在),輸出父節(jié)點的序號和名字,并將信息記錄到 QPlainTextEdit 中。
以下是概述:
-
獲取當前選中節(jié)點的父節(jié)點: 使用
QTreeWidgetItem *currentItem = ui->treeWidget->currentItem()->parent();獲取當前選中節(jié)點的父節(jié)點。 -
獲取父節(jié)點在*節(jié)點中的序號: 使用
int root_count = ui->treeWidget->indexOfTopLevelItem(currentItem);獲取父節(jié)點在*節(jié)點中的序號。 -
判斷是否存在父節(jié)點: 使用
if(root_count != -1)條件判斷,如果存在父節(jié)點,執(zhí)行下面的操作;否則,直接返回。 -
獲取指定序號對應的父節(jié)點: 使用
child = ui->treeWidget->topLevelItem(root_count);獲取指定序號對應的父節(jié)點。 -
輸出父節(jié)點的序號和名字: 使用
std::cout << "root Count = " << root_count << std::endl;輸出父節(jié)點在*節(jié)點中的序號,以及std::cout << "root name= "<< child->text(0).toStdString().data() << std::endl;輸出父節(jié)點的名字。 -
記錄操作到
QPlainTextEdit中: 使用ui->plainTextEdit->appendPlainText("獲取父節(jié)點ID");將一行文本記錄添加到QPlainTextEdit中,用于記錄操作。
這段代碼的作用是在點擊按鈕時,獲取當前選中節(jié)點的父節(jié)點(如果存在),輸出父節(jié)點在*節(jié)點中的序號和名字,并將信息記錄到 QPlainTextEdit 中。
void MainWindow::on_pushButton_getnode_clicked()
{
// 取所有的父節(jié)點
QTreeWidgetItem *currentItem = ui->treeWidget->currentItem()->parent();
int root_count = ui->treeWidget->indexOfTopLevelItem(currentItem);
std::cout << "root Count = " << root_count << std::endl;
if(root_count != -1)
{
// 指定序號對應的父節(jié)點名字
QTreeWidgetItem *child;
child = ui->treeWidget->topLevelItem(root_count);
std::cout << "root name= "<< child->text(0).toStdString().data() << std::endl;
ui->plainTextEdit->appendPlainText(child->text(0).toStdString().data());
}
ui->plainTextEdit->appendPlainText("獲取父節(jié)點ID");
}
當用戶選中一個子節(jié)點時,可通過該槽函數(shù)獲取其父節(jié)點的ID編號,如下圖;
1.9 綁定右鍵菜單
在開發(fā)中我們經(jīng)常會把它當作一個升級版的ListView組件使用,因為ListView每次只能顯示一列數(shù)據(jù)集,而使用TableWidget組件顯示多列顯得不夠美觀,此時使用TreeWidget組件顯示單層結(jié)構(gòu)是最理想的方式,同時該組件同樣支持增加右鍵菜單,在真正的開發(fā)中尤為常用。
首先我們在MainWindow主窗體中只保留一個treeWidget組件,接著直接來到MainWindow構(gòu)造函數(shù)上,在該函數(shù)中我們通過動態(tài)創(chuàng)建一個menuBar()并將其隱藏起來,接著將菜單屬性與treeWidget中的事件相互綁定,最后初始化填充一些測試數(shù)據(jù),其代碼如下;
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{
ui->setupUi(this);
// -------------------------------------------------
// 初始化組件菜單
// -------------------------------------------------
// 在MainWindow中使用右擊菜單需要添加此項
ui->treeWidget->setContextMenuPolicy(Qt::CustomContextMenu);
// 創(chuàng)建基礎(chǔ)頂部菜單
QMenuBar *bar = menuBar();
this->setMenuBar(bar);
QMenu * fileMenu = bar->addMenu("菜單1");
// 實現(xiàn)只隱藏菜單1其他的不受影響
fileMenu->menuAction()->setVisible(false);
// 添加子菜單
GetColumnAction = fileMenu->addAction("獲取列號");
GetRowDataAction = fileMenu->addAction("獲取本行數(shù)據(jù)");
GetLineAction = fileMenu->addAction("獲取行號");
// 分別設置圖標
GetColumnAction->setIcon(QIcon(":/image/1.ico"));
GetRowDataAction->setIcon(QIcon(":/image/2.ico"));
GetLineAction->setIcon(QIcon(":/image/3.ico"));
// 為子菜單綁定熱鍵
GetColumnAction->setShortcut(Qt::CTRL | Qt::Key_A);
GetRowDataAction->setShortcut(Qt::SHIFT | Qt::Key_S);
GetLineAction->setShortcut(Qt::CTRL | Qt::SHIFT | Qt::Key_B);
// -------------------------------------------------
// 綁定槽函數(shù)
// -------------------------------------------------
// 綁定槽函數(shù): 獲取選中列
connect(GetColumnAction,&QAction::triggered,this,[=](){
int col = ui->treeWidget->currentColumn();
std::cout << col << std::endl;
});
// 綁定槽函數(shù): 獲取選中的第0行的數(shù)據(jù)內(nèi)容
connect(GetRowDataAction,&QAction::triggered,this,[=](){
QString msg = ui->treeWidget->currentItem()->text(0);
std::cout << msg.toStdString().data() << std::endl;
});
// 綁定槽函數(shù): 獲取當前選中的索引值
connect(GetLineAction,&QAction::triggered,this,[=](){
int row = ui->treeWidget->currentIndex().row();
std::cout << row << std::endl;
});
// -------------------------------------------------
// 設置屬性填充數(shù)據(jù)
// -------------------------------------------------
// 設置treeWidget屬性
ui->treeWidget->setColumnCount(4); // 設置總列數(shù)
ui->treeWidget->setColumnWidth(0,300); // 設置最后一列寬度自適應
ui->treeWidget->setIndentation(1); // 設置表頭縮進為1
// 設置表頭數(shù)據(jù)
QStringList headers;
headers.append("文件名");
headers.append("更新時間");
headers.append("文件類型");
headers.append("文件大小");
ui->treeWidget->setHeaderLabels(headers);
// 模擬插入數(shù)據(jù)到表中
for(int x=0;x<100;x++)
{
QTreeWidgetItem* item=new QTreeWidgetItem();
item->setText(0,"《LyShark 從入門到精通》");
item->setIcon(0,QIcon(":/image/1.ico"));
item->setText(1,"2023-12-17");
item->setText(2,"*.pdf");
item->setText(3,"102MB");
item->setIcon(3,QIcon(":/image/2.ico"));
ui->treeWidget->addTopLevelItem(item);
}
}
此時,當treeWidget中的右鍵被點擊后則將觸發(fā)on_treeWidget_customContextMenuRequested槽函數(shù),此函數(shù)中動態(tài)的新建一個菜單,并在鼠標點擊位置將其顯示輸出,代碼如下;
// 當treeWidget中的右鍵被點擊時則觸發(fā)
void MainWindow::on_treeWidget_customContextMenuRequested(const QPoint &pos)
{
std::cout << "x pos = "<< pos.x() << "y pos = " << pos.y() << std::endl;
Q_UNUSED(pos);
// 新建Menu菜單
QMenu *ptr = new QMenu(this);
// 添加Actions創(chuàng)建菜單項
ptr->addAction(GetColumnAction);
ptr->addAction(GetLineAction);
// 添加一個分割線
ptr->addSeparator();
ptr->addAction(GetRowDataAction);
// 在鼠標光標位置顯示右鍵快捷菜單
ptr->exec(QCursor::pos());
// 手工創(chuàng)建的指針必須手工刪除
delete ptr;
}
運行后讀者可看到如下圖所示的輸出效果;
完整案例下載
總結(jié)
以上是生活随笔為你收集整理的C++ Qt开发:TreeWidget 树形选择组件的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java五种设计模式实现奶茶订单生成系统
- 下一篇: 处理器架构和配置