翻譯|使用教程|編輯:顏馨|2023-05-12 13:53:40.583|閱讀 244 次
概述:本章講述Qt小部件:可編輯樹模型的示例,歡迎查閱~
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
相關鏈接:
Qt 是目前最先進、最完整的跨平臺C++開發(fā)工具。它不僅完全實現(xiàn)了一次編寫,所有平臺無差別運行,更提供了幾乎所有開發(fā)過程中需要用到的工具。如今,Qt已被運用于超過70個行業(yè)、數(shù)千家企業(yè),支持數(shù)百萬設備及應用。
The Qt Company是Digia Plc旗下的全資子公司。負責所有Qt活動,包括產(chǎn)品開發(fā),商業(yè)和開源授權模式以及在開放管理模式下的Qt工程。其許可、支持和服務能力能夠和開發(fā)者緊密合作以確保他們的Qt項目準時部署,不超預算并擁有競爭優(yōu)勢。
Qt技術交流群:166830288
此示例演示如何實現(xiàn)一個簡單的基于項的樹模型,該模型可與模型/視圖框架的其他類一起使用。
該模型支持可編輯項、自定義標題以及插入和刪除行和列的功能。使用這些功能,還可以插入新的子項,這在支持的示例代碼中顯示。
如模型子類化參考中所述,模型必須為標準模型函數(shù)集提供實現(xiàn):flags()、data()、headerData()、columnCount() 和 rowCount()。此外,分層模型,比如這個,需要提供 index() 和 parent() 的實現(xiàn)。
可編輯模型需要提供 setData() 和 setHeaderData() 的實現(xiàn),并且必須從其 flags() 函數(shù)返回合適的標志組合。
由于這個例子允許改變模型的維度,我們還必須實現(xiàn)insertRows(),insertColumns(),removeRows()和removeColumns()。
與簡單樹模型示例一樣,該模型只是充當類實例集合的包裝器。每個都旨在保存樹視圖中一行項目的數(shù)據(jù),因此它包含與每列中顯示的數(shù)據(jù)對應的值列表。
由于 QTreeView 為模型提供了面向行的視圖,因此很自然地為數(shù)據(jù)結(jié)構(gòu)選擇面向行的設計,該設計將通過模型向此類視圖提供數(shù)據(jù)。盡管這使得樹模型不太靈活,并且對于用于更復雜的視圖可能不太有用,但它使設計變得不那么復雜,并且更易于實現(xiàn)。
在設計用于自定義模型的數(shù)據(jù)結(jié)構(gòu)時,通過 TreeItem::p arent() 等函數(shù)公開每個項的父項很有用,因為它將使編寫模型自己的 parent() 函數(shù)更容易。類似地,像 TreeItem::child() 這樣的函數(shù)在實現(xiàn)模型的 index() 函數(shù)時很有幫助。因此,每個都維護有關其父級和子級的信息,使我們能夠遍歷樹結(jié)構(gòu)。該圖顯示了實例如何通過其 parent() 和 child() 函數(shù)進行連接。
在所示的示例中,可以通過調(diào)用其 child() 函數(shù)從根項獲取兩個頂級項 A 和 B,并且這些項中的每一個都從其 parent() 函數(shù)返回根節(jié)點,盡管這僅針對項 A 顯示。
每個都在其私有成員(QVariant 對象列表)中表示的行中存儲每一列的數(shù)據(jù)。由于視圖中的每一列和列表中的每個條目之間存在一對一的映射,因此我們提供了一個簡單的 data() 函數(shù)來讀取列表中的條目,并提供了一個 setData() 函數(shù)來允許修改它們。與項目中的其他函數(shù)一樣,這簡化了模型的 data() 和 setData() 函數(shù)的實現(xiàn)。
我們將一個項目放在項目樹的根目錄中。此根項對應于空模型索引 QModelIndex(),該索引用于在處理模型索引時表示頂級項的父項。盡管根項在任何標準視圖中都沒有可見的表示形式,但我們使用其內(nèi)部 QVariant 對象列表來存儲字符串列表,這些字符串將傳遞給視圖以用作水平標題。
在圖中所示的情況下,可以使用標準模型/視圖 API 獲取由 a 表示的信息片段:
QVariant a = model->index(0, 0, QModelIndex()).data();
由于每個項目都包含給定行中每一列的數(shù)據(jù)片段,因此可以有許多映射到同一對象的模型索引。例如,可以使用以下代碼獲取 b 表示的信息:TreeItem
QVariant b = model->index(1, 0, QModelIndex()).data();
同樣的底層將被訪問以獲得與b.TreeItem相同行的其他模型索引的信息。
在模型類中,當我們在 index() 和 parent() 實現(xiàn)中使用 QAbstractItemModel::createIndex() 創(chuàng)建相應的模型索引時,我們通過為每個項目傳遞一個指針來將對象與模型索引相關聯(lián)。我們可以通過在相關模型索引上調(diào)用 internalPointer() 函數(shù)來檢索以這種方式存儲的指針 - 我們創(chuàng)建自己的 getItem() 函數(shù)來為我們完成工作,并從我們的 data() 和 parent() 實現(xiàn)中調(diào)用它。
當我們控制項目的創(chuàng)建和銷毀方式時,存儲指向項目的指針很方便,因為我們可以假設從 internalPointer() 獲得的地址是有效的指針。但是,某些模型需要處理從系統(tǒng)中的其他組件獲取的項,并且在許多情況下,無法完全控制項的創(chuàng)建或銷毀方式。在這種情況下,純基于指針的方法需要輔以保護措施,以確保模型不會嘗試訪問已刪除的項目。
幾段數(shù)據(jù)作為 QVariant 對象存儲在每個實例的成員中。
該圖顯示了由前兩個圖中的標簽 a、b 和 c 表示的信息片段如何存儲在基礎數(shù)據(jù)結(jié)構(gòu)中的項目 A、B 和 C 中。請注意,模型中同一行的信息片段都是從同一項目獲取的。列表中的每個元素對應于模型中給定行中每列公開的一條信息。
由于該實現(xiàn)是為與 QTreeView 一起使用而設計的,因此我們對其使用實例的方式添加了限制:每個項目必須公開相同數(shù)量的數(shù)據(jù)列。這使得查看模型保持一致,允許我們使用根項來確定任何給定行的列數(shù),并且僅添加創(chuàng)建包含足夠列數(shù)數(shù)據(jù)的項的要求。因此,插入和刪除列是耗時的操作,因為我們需要遍歷整個樹來修改每個項目。
另一種方法是設計類,以便在修改數(shù)據(jù)項時截斷或擴展單個實例中的數(shù)據(jù)列表。但是,這種“懶惰”的大小調(diào)整方法只允許我們在每行的末尾插入和刪除列,而不允許在每行的任意位置插入或刪除列。
與簡單樹模型示例一樣,需要能夠獲取模型索引,找到相應的 ,并返回與其父項和子項對應的模型索引。
在圖中,我們展示了模型的 parent() 實現(xiàn)如何使用上圖中顯示的項獲取與調(diào)用方提供的項的父項對應的模型索引。
指向項 C 的指針是使用 QModelIndex::internalPointer() 函數(shù)從相應的模型索引中獲取的。指針在創(chuàng)建時存儲在索引內(nèi)部。由于子項包含指向其父項的指針,因此我們使用其 parent() 函數(shù)來獲取指向項 B 的指針。父模型索引是使用 QAbstractItemModel::createIndex() 函數(shù)創(chuàng)建的,將指向項 B 的指針作為內(nèi)部指針傳遞。
歡迎下載|體驗更多Qt產(chǎn)品
獲取更多信息請咨詢 ;Qt技術交流群:166830288
本站文章除注明轉(zhuǎn)載外,均為本站原創(chuàng)或翻譯。歡迎任何形式的轉(zhuǎn)載,但請務必注明出處、不得修改原文相關鏈接,如果存在內(nèi)容上的異議請郵件反饋至chenjj@fc6vip.cn