QTreeWidget Qt最常用最好用的樹狀列表窗體
引言
為什麼不能通過這篇文章,直接玩轉 QTreeWidget
樹樁窗體呢?
簡介
作業系統:window7 x64
程式設計IDE:Qt Creator 4.2.1
Qt版本:5.8.0
最後更新日期:2017年5月3日
基礎
這裡只負責基礎的內容,最淺顯,最常用的內容。
樹狀列表的建立
關聯
該類的關聯標頭檔案, 別覺得誰都知道,有不知道的人,我說真的。
#include <QTreeWidget>
光膀子的列表
包含了標頭檔案以後,我們通過下面的這句話就可以建出一個啥也沒有的列表了,雖然這個列表看起來還很可笑。QTreeWidget*
別瞧他現在還是個四不像,這胚子已經出來了,樹狀列表還遠嗎?
這裡的1
是這個樹狀圖的標題,我們暫時先不用理會他。穿上列表的衣服
我們來認識下一個至關重要的類。
QTreeWidgetItem
顯然他的名字就已經說明了他的作用,我們想要插入一條一條的資料都要通過這個類。/** * @brief : 建構函式 - 生成一個子項 * @param : view 關聯的窗體,或譯父節點 * @param : strings 列(column)資料 (後面會細講) * @param
我們來建立我們自己的列表
QTreeWidget* tree = new QTreeWidget(); tree->show(); //新增一級節點 QTreeWidgetItem *items1 = new QTreeWidgetItem(tree, QStringList(QString("num_1"))); QTreeWidgetItem *
我們的樹列就有了,一個for,我們想有多少行就有多少行了。
至此,基礎的列表顯示就已經齊全了。
樹狀列表的刪除
野蠻的 delete
樹狀列表的刪除其實很有趣,一個
delete
就搞定了,儘管這樣很不優雅。原因也很簡單,一個
delete
觸發了解構函式。我說他野蠻的原因是,我們不可能在程式複雜的執行過程中還保留曾經的變數 items2 item3….
所以這樣的寫法,只能被看成野蠻,無腦。
如何優雅?
QTreeWidget* tree = new QTreeWidget(); tree->show(); //新增一級節點 QTreeWidgetItem *items1 = new QTreeWidgetItem(tree, QStringList(QString("num_1"))); QTreeWidgetItem *items2 = new QTreeWidgetItem(tree, QStringList(QString("num_2"))); QTreeWidgetItem *items3 = new QTreeWidgetItem(tree, QStringList(QString("num_3"))); tree->takeTopLevelItem(1);
嘿嘿,這裡的函式名
takeTopLevelItem
已經闡述了他的作用,拿走頂級的項。
index 是下標,我們這裡給了1
你們可以想想,這裡哪個子項會消失。最常用的刪除
我們一般刪除某個項,都是由使用者通過滑鼠指定的,所以我們其實可以通過相應特定的事件(例:右鍵選單,delete keydown)。
// 通過這個函式獲得當前選中的項 QTreeWidget* tree = new QTreeWidget(); tree->currentItem();
若currentItem 返回空,則意味著沒有選中該列表中的子項。
樹狀圖的查詢
眾裡尋他千百度 刪他只需一抽搐
QTreeWidget* tree = new QTreeWidget(); tree->show(); //新增一級節點 QTreeWidgetItem *items1 = new QTreeWidgetItem(tree, QStringList(QString("num_1"))); QTreeWidgetItem *items2 = new QTreeWidgetItem(tree, QStringList(QString("num_1"))); QTreeWidgetItem *items3 = new QTreeWidgetItem(tree, QStringList(QString("num_3"))); // 查詢 與 num_1 完全一致的項,並返回。 QList<QTreeWidgetItem*> s = tree->findItems("num_1", Qt::MatchFlag::MatchExactly); // 無情刪除 for (auto item : s) { delete item; }
深入
多級樹狀圖
多級樹狀圖,其實也很好理解,就是把父節點換掉嘛,誰是父節點,那麼Item項就掛載在誰的下面。
QTreeWidgetItem *items3 = new QTreeWidgetItem(tree,
QStringList(QString("num_13")));
QTreeWidgetItem *item104 = new QTreeWidgetItem(items3,
QStringList(QString("item104")));
層次都是按照這個套路來的,多級樹狀圖油然而生。
多列樹狀圖
暫無資訊
簡單的自定義
使用這個函式的時候,需要在全域性或類內定義一個變數
QMap<QString, QTreeWidgetItem*> itemMap_
, 他記錄著所有樹列的唯一鍵值,記住是唯一。
/**
* @brief : 新增子項到樹中
* @param : item 項的內容
* @param : parentKey 他的父級節點的唯一標識
* @param : theKey 他的節點唯一標識
*/
int CustomTreeWidget::addItem(QStringList item, QString parentKey, QString theKey) {
QTreeWidgetItem* temp_item;
/// 生成到父級節點下
QMap<QString,QTreeWidgetItem*>::iterator iter_item = itemMap_.find(parentKey);
if (iter_item == itemMap_.end()) {
temp_item = new QTreeWidgetItem(this, item);
}
else {
temp_item = new QTreeWidgetItem(iter_item.value(), item);
}
/// 判斷
if (!theKey.isEmpty()) {
itemMap_.insert(theKey,temp_item);
}
}
這裡只是簡單的給大家一個思路,大家放膽去繼承QTreeWidget類,發揮想象讀取幹吧。
比如通過某個值獲得這個項,結合上面的基礎,已經可以做很多事情啦,不是嗎?
列表頭的操作
- 表頭操作
/**
* @brief : 表頭的隱藏
* @param : hide [true : 隱藏表頭 false : 顯示錶頭]
*/
void QTreeView::setHeaderHidden(bool hide);
- 設定表頭
/**
* @brief : 設定表頭內容
* @param : item 具體的item項
*/
void QTreeView::setHeaderItem(QTreeWidgetItem *item);
// 也可以直接給文字
void setHeaderLabels(const QStringList &labels);
inline void setHeaderLabel(const QString &label);
會說話的顏色
QStringList head;
head << "姓名";
QTreeWidget* tree = new QTreeWidget();
tree->show();
// 設定表頭
tree->setHeaderLabels(head);
// 新增一級節點
head.clear();
head << "王根基";
QTreeWidgetItem *items1 = new QTreeWidgetItem(tree,
head);
head.clear();
head << "李大錘";
QTreeWidgetItem *items3 = new QTreeWidgetItem(tree,
head);
/// 設定背景顏色
items3->setBackground(0,QBrush(Qt::green));
head.clear();
head << "李思基(非親生)";
QTreeWidgetItem *item104 = new QTreeWidgetItem(items3,
head);
太晚了,這裡還沒有更新,抱歉。
為子項新增Logo
暫無介紹
QTreeWidget 的新裝
暫無介紹