Qt——樹結點的搜索


一、Qt中的樹

平時我們經常使用樹的結構來組織和展示數據,比如文件系統等——

在Qt中,我們可以使用Qt提供的便捷的QTreeWidget類,利用該類的接口,輕松地將已有數據顯示在樹中。

除此之外,還可以使用QTreeView,設置它的數據模型,比如QStandardItemModel,我們可以根據自己需要實現更多功能,尤其是在做數據同步的時候特別方便。

 

二、結點的搜索

在實際的應用中,我們可能需要進行結點的搜索,也就是根據關鍵字過濾出匹配的項,隱藏不匹配的項。

根據我的經驗,一般是在界面中樹的上面放一個搜索輸入框。可以根據輸入內容精確匹配,也可以根據輸入的首字母匹配結點中的漢字。

其實這就是一個樹的遍歷的問題,遍歷的方式可以使用遞歸。

一般搜索方式有兩種:精確搜索和模糊搜索。下面我分兩部分說明,假設樹中節點文字有漢字、英文、數字。

精確搜索

搜索框中輸入漢字時使用精確搜索,我所設計的並不是嚴格意義上的精確搜索。

比如對於文本“東京不太熱Miao”,輸入“京”、“太熱”、“不太熱mi”等關鍵字都能搜到,但是如果輸入“京東”那就不匹配了。

模糊搜索

模糊搜索也就是拼音搜索,輸入漢字的拼音首字母就能搜到它,比如對於“東京不太熱Miao”,輸入“djbtr”、“btr”、“trm”、“trM”等關鍵字都能搜到。

我給拼音首字母搜索加了點功能,就是輸入全拼時也能搜索,但必須從第一個漢字的拼音開始,比如“dongjingb”匹配,但是“jingbutaire”就不匹配了。

 

三、功能實現

如何區分精確搜索和模糊搜索

搜索框中的輸入全部是英文字母或數字時,使用模糊搜索;否則,如果有漢字,則使用精確搜索。

搜索方式

因為樹有很多級,所以需要使用遞歸遍歷所有節點。將每個節點上的文本與你輸入的關鍵字進行比較,如果匹配,則顯示該節點、它的所有父節點、它的所有子節點,如果不匹配,繼續遍歷其子節點,循環往復,如果找不到匹配,則將其隱藏。

 

四、難點

樹的搜索很簡單,然而將漢字轉為拼音很麻煩,雖然網上很多很多實現,但都存在缺點。很大一部分是先將漢字轉為ascii,然后獲得其拼音的ascii,繼而得到拼音和首字母。這種方式的缺點是很多生僻字以及部分常見字搜不出來,但對於一般樹的搜索已經夠用了。另一種方式是窮舉,將所有可能的情況都列舉出來,但是這樣做要列舉很多很多情況,占的空間多,而且查詢效率也很低。

 

五、程序優化

我實現樹的搜索是在一位同事的基礎上修改的,他是這樣實現的:每次搜索框發生改變,都將之前的樹清空,然后重新建立樹,如果樹節點中保存了一些數據,它們將會丟失,或者你需要大費周折才能將數據恢復。

我將節點的增刪,修改成了節點的隱藏顯示。

然后對樹的搜索進行了封裝,最后提供了一個靜態函數static void SearchItem(QTreeWidget *, const QString &);

只需傳2個參數,一個是你所需要搜索的樹,另一個是搜索的關鍵字,就能對樹進行搜索了。

不多說了,分享我所實現類的頭文件部分源碼——

class TreeSearch
{
public:
	TreeSearch();
	~TreeSearch();
	static void SearchItem(QTreeWidget *, const QString &);//搜索函數

private:
	static void FuzzySearch(QString &);								//模糊搜索
	static void FuzzySearchChildren(QTreeWidgetItem *, QString &);	//模糊搜索子節點(遞歸)
	static void PreciseSearch(const QString &);						//精確搜索
	static void PreciseSearchChildren(QTreeWidgetItem *, const QString &);//精確搜索子節點(遞歸)
	static void ShowTotalItem();									//顯示所有節點
	static void ShowTotalChildrenItem(QTreeWidgetItem *);				//顯示所有子節點(遞歸)
	static void ShowTotalParentItem(QTreeWidgetItem *);				//設置所有父節點可顯示(遞歸)
	static void GetPinYin(const QString &, QString &strInitial, QString &strQuanPin);	//將漢字轉為拼音(首字母以及全拼)
	static void GetWString(const std::string &, std::wstring &wStrOut);//將string轉為wstring

private:
	static QTreeWidget *m_pCurTreeWidget;			//當前的樹
};

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM