天天看點

Qt QTreeWidget 樹形結構實作(上)

此文章轉自他人,隻是為了友善自己整理資料以及大家共同進步而釋出。

轉自:http://www.cnblogs.com/Romi/archive/2012/04/16/2452709.html

Qt中實作樹形結構可以使用QTreeWidget類,也可以使用QTreeView類,QTreeWidget繼承自QTreeView類。樹形效果如下圖所示:

Qt QTreeWidget 樹形結構實作(上)

這是怎麼實作的呢?還有點選節點時會有相應的事件響應。

1. 樹形結構實作

QT GUI中有treeWidget部件,将該控件在Gui中布局好,假設其對象名為treeWidget。

QTreeWidget類官方文檔:http://qt-project.org/doc/qt-4.8/qtreewidget.html

樹形結構通過QTreeWidget類和QTreeWidgetItem類實作,QTreeWidgetItem類實作結點的添加。上圖代碼實作如下:

Qt QTreeWidget 樹形結構實作(上)
ui->treeWidget->setColumnCount(1); //設定列數
ui->treeWidget->setHeaderLabel(tr("圖像選擇")); //設定頭的标題

QTreeWidgetItem *imageItem1 = new QTreeWidgetItem(ui->treeWidget,QStringList(QString("圖像1")));
imageItem1->setIcon(0,QIcon("xxx.png"));
QTreeWidgetItem *imageItem1_1 = new QTreeWidgetItem(imageItem1,QStringList(QString("Band1"))); //子節點1
imageItem1->addChild(imageItem1_1); //添加子節點

QTreeWidgetItem *imageItem2 = new QTreeWidgetItem(ui->treeWidget,QStringList(QString("圖像2")));
QTreeWidgetItem *imageItem2_1 = new QTreeWidgetItem(imageItem2,QStringList(QString("Band1"))); //子節點1
QTreeWidgetItem *imageItem2_2 = new QTreeWidgetItem(imageItem2,QStringList(QString("Band2"))); //子節點2
imageItem2->addChild(imageItem2_1);  //添加子節點
imageItem2->addChild(imageItem2_2);

ui->treeWidget->expandAll(); //結點全部展開      
Qt QTreeWidget 樹形結構實作(上)

當然,還有其他的一些方法用于設定,具體需要時查查幫助文檔學習。

除了使用上面這種方法之外,還可以使用QList<QTreeWidgetItem *> & items實作結點的添加。QT中對C++中的STL庫中的容器使用進行了封裝,使用其封裝的類可以很友善的解決很多類似很複雜資料結構的問題。實作如下:

Qt QTreeWidget 樹形結構實作(上)
//隻寫結點的實作
QList<QTreeWidgetItem *> rootList;

QTreeWidgetItem *imageItem1 = new QTreeWidgetItem;   //添加第一個父節點
imageItem1->setText(0,tr("圖像1"));
rootList.append(imageItem1);

QTreeWidgetItem *imageItem1_1 = new QTreeWidgetItem(imageItem1,QStringList(QString("Band1"))); //添加子節點
imageItem1->addChild(imageItem1_1);

QTreeWidgetItem *imageItem2 = new QTreeWidgetItem;   //添加第二個父節點
imageItem2->setText(0,tr("圖像2"));
rootList.append(imageItem2);

QTreeWidgetItem *imageItem2_1 = new QTreeWidgetItem(imageItem2,QStringList(QString("Band1")));  //添加子節點
QTreeWidgetItem *imageItem2_2 = new QTreeWidgetItem(imageItem2,QStringList(QString("Band2")));
imageItem2->addChild(imageItem2_1);
imageItem2->addChild(imageItem2_2);

ui->treeWidget->insertTopLevelItems(0,rootList);  //将結點插入部件中

ui->treeWidget->expandAll(); //全部展開      
Qt QTreeWidget 樹形結構實作(上)

2. 點選節點的事件響應

首先想到有沒有點選某個節點的信号,檢視文檔,有一個void itemClicked ( QTreeWidgetItem * item, int column )信号,是輕按兩下某個節點的信号,将該信号與某個自定義槽相連,當輕按兩下節點時觸發槽函數。

看一下這個信号,第一個參數為點選的QTreeWidgetItem類對象,第二個參數為節點所在列号。

思路:根據點選的QTreeWidgetItem類對象可以通過parent()函數得到父節點,如果QTreeWidgetItem類對象就是最最頂端的節點時,parent()函數傳回的就是NULL。通過insertChildren ( int index, const QList<QTreeWidgetItem *> & children )函數可以得到該節點在父節點中的索引值。

目前隻能解決隻有一個最頂端父節點時的事件響應,當最頂端的父節點有多個(比如本文開頭有2個),這時點選子節點時,無法判斷子節點的父節點是哪一個(本人愚笨啊!),是以沒法為其槽函數執行相應的操作。

這裡就以一個分支為例。

Qt QTreeWidget 樹形結構實作(上)
1 private slots:
 2     void showSelectedImage(QTreeWidgetItem * item, int column); //點選樹節點事件
 3 
 4 connect(ui->treeWidget,SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)),this,SLOT(showSelectedImage(QTreeWidgetItem*,int)));
 5 
 6 void MainWindow::showSelectedImage(QTreeWidgetItem *item, int column)
 7 {
 8     QTreeWidgetItem *parent = item->parent();
 9     if(NULL==parent) //注意:最頂端項是沒有父節點的,輕按兩下這些項時注意(陷阱)
10         return;
11     int col = parent->indexOfChild(item); //item在父項中的節點行号(從0開始)
12 
13     if(0==col) //Band1
14     {
15         //執行對應操作
16     }
17     if(1==col) //Band2
18     {
19         //執行對應操作
20     }
21 }      
Qt QTreeWidget 樹形結構實作(上)

如果不加父節點是否為空的判斷,當節點有父節點時,不會出錯,當節點沒有父節點時,程式會出錯(運作錯誤),判斷之後,輕按兩下沒有父節點的節點就會是樹的收縮操作。

繼續閱讀