zoukankan      html  css  js  c++  java
  • 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;			//当前的树
    };
    

      

  • 相关阅读:
    celery 大量消息的分布式系统 定时任务
    小程序开发-生活娱乐两不误
    linux安装selenium+chrome+phantomjs
    CENTOS 7 安装 TINYPROXY 代理服务器
    JVM(三) 垃圾回收时间点和垃圾收集器
    JDK12 concurrenthashmap源码阅读
    JVM(二) 对象存活判断和垃圾回收算法
    java 线程池(2)
    JVM(一)
    java 线程池(1)
  • 原文地址:https://www.cnblogs.com/hellovenus/p/5146947.html
Copyright © 2011-2022 走看看