一个耄耋耐心的程序员无意中帮助本座解决了一个问题
本座今天一整天的时间都花在一个关于Q t 的问题上,牵涉到了Qt中的 QComboBox、QSqlRelationalTableModel、QSortFilterProxyModel、QListView 。找了一天 ,最后终于在一个程序员的一个不直接相关的帖子中找到满意的解决方法了 。
本座要做的事就是用一个 QComboBox列出一个数据库表中的某一列 。本座使用了一个 QSqlRelationalTableModel来从数据库中取数据,由于还有其它的对象要过滤并且使用这个数据,因此本座先将一个 QSortFilterProxyModel连接到这个 QSqlRelationalTableModel ,再将 QComboBox连接到这个 QSortFilterProxyModel ,以免为这个QComboBox而做的过滤与其它对象互相影响。数据流向就是这样的 :
QSqlRelationalTableModel => QSortFilterProxyModel => QComboBox
碰到的问题就是 ,QComboBox显示的是 QSqlRelationalTableModel的数据中的一列 ,而这一列的数据是有重复的,本座不想让 QComboBox里面出现重复的条目 。本座直接想到的方法就是过滤 、删除、隐藏。
QSqlRelationalTableModel里的数据要跟其它对象共享,所以最好不要在它上面做动作 ,排个序还是可以接受的 ,但是要直接在它上面过滤是不行的 。 QSortFilterProxyModel本来就是设计用于为 QComboBox过滤数据的 ,所以可以考虑在它上面过滤。 QComboBox自身可能也有接口能做到本座要求的事 ,因此对它的处理也在考虑之中。另外,还可以给 QComboBox指定一个外部的 QListView对象来控制它的显示 ,看起来这也跟问题相关,因此也可以考虑使用 QListView的接口来实现。所以 ,总共有3个类 ,它们都是有可能解决这个问题的 。
由于 QListView本身就是视图 ,就是用于处理显示相关的事务的,因此本座首先就找它的接口了,看看有没有类似“hideItem”这样的函数。很遗憾地是 ,本座看了它的文档,还看了它所继承的类的文档,都耄耋“hideItem”或者其它的让本座觉得那能隐藏某个条目的函数。
下一个本座觉得相对简单一点的就是 QComboBox了 ,看看它的文档 ,这次本座很高兴地发现了 “ removeItem ”这个函数。这就好说了 ,嘿嘿。找出重复的条目不是什么难事 ,所以本座就写了代码,把找到的重复条目用这个函数删除了。正在高兴地 ,再一测试 ,感觉到不对劲了。去数据库里一看哪 ,原来在 QComboBox里做 removeItem的时候 ,导致数据库里的记录被删除了。一想 ,原来是这样的 :在 QComboBox里做的删除操作通过 QSortFilterProxyModel 、 QSqlRelationalTableModel传递到数据库里面 ,将对应的记录直接删除了。搞个鸟啊,这还得了,不能这么用。
那就只好去研究怎么对 QSortFilterProxyModel下手了 。去看它的文档 ,通过重载filterAcceptsRow这个函数能够实现将你不想让用户看到的行过滤掉 。于是本座就准备这么做了 。那就开始看看跟它相关的文档了 。就在这个时候 ,本座碰巧看到了 QtCenter论坛上的 这个帖子 。叫做 peterius的这个人一上来就直接说Qt的模型/视图框架做得不好,有个问题他搞了一年还没搞好,就是因为Qt不好的原因。当别人让他贴出自己的代码帮他分析时 ,他很不愿意 ,骂别人是外行 ,而且不贴上自己的代码。本座本来想一直看到帖子的最后,看看他的态度到底能恶劣到什么程度 ,结果一不小心从他的一个回复里看到他说setRowHidden这个函数工作不正常的话 ,本座当时就眼前一亮,嘿嘿,这很可能就是本座要找的 东西啊。马上去看 Qt的文档,原来 QListView、QTableView、QTreeView三个标准的视图类都有这个函数的,作用就是切换某一行的隐藏状态。这果然就是本座要找的东西。原来本座在搜索 Qt文档的时候用的是关键字“hide”,而“hidden”正好被排除在外,也许Qt可以考虑将单词的变体也包含在搜索索引中呢 。
使用 setRowHidden函数 ,本座的问题很快解决了。感谢这个哥哥无意中说出了本座想要的东西 ,另外祝愿他以后看问题能冷静点 ,态度不要那么差。
Your opinionsHxLauncher: Launch Android applications by voice commands