0

当我将自己的QCompleterQAbstractItemModel一起使用时,我在 PySide 中看到了一种奇怪的行为,而且我在 PySide(或 Qt 中)中找不到解释它在做什么的文档。

当我有一个使用 QCompleter 的编辑框并输入其他字符时,有大量调用来QAbstractItemModel.data()获取大量项目的完成列内容。此调用针对相关的项目发生,每个项目多次,但也针对根目录下的每个顶级项目。

由于我的数据模型中有数百个(甚至可能是数千个)顶级项目,我有点担心我做错了什么。我只是想确保它不会让我的计算机陷入不相关的计算。

我在这里创建了一个示例:https ://gist.github.com/jason-s/6c9495e29a4caac7ddf5cd739550a310 我基于我之前在另一个问题中的示例

如果我运行它python qtcompleter5.py -e 25United States/Arizona/P在编辑框中键入,我在控制台中看到的内容如下所示。(这些Miragi012stan条目是故意的,通过改变参数来轻松改变顶级项目数-e。)

splitPath:  [u'United States', u'Arizona', u'P']
Canada
France
Germany
United States
Mexico
Miragi000stan
Miragi001stan
Miragi002stan
Miragi003stan
Miragi004stan
Miragi005stan
Miragi006stan
Miragi007stan
Miragi008stan
Miragi009stan
Miragi010stan
Miragi011stan
Miragi012stan
Miragi013stan
Miragi014stan
Miragi015stan
Miragi016stan
Miragi017stan
Miragi018stan
Miragi019stan
Miragi020stan
Miragi021stan
Miragi022stan
Miragi023stan
Miragi024stan
Peoria
Peoria
Phoenix
Peoria
Peoria
Peoria
Peoria
Phoenix
Phoenix

在我看来.data(),所有顶级项目都被调用,然后可能与完成窗口中的文本匹配的实际项目被调用 3-6 次。

唯一不这样做的时候是当我输入顶级项目时,例如Unite产生这些调用:

splitPath:  [u'Unite']
United States
United States
United States
splitPath:  [u'Unite']
United States
United States
United States
United States
United States

(顺便说一句,我可以注释掉 TreeView 的东西,只留下 QLineEdit,所以 TreeView 不是导致问题的部分。)

即使我尝试通过告诉 PySide 我正在使用排序模型(参见qtcompleter5a.py)来提供帮助,也会发生相同的行为(查询所有顶级项目)completer.setModelSorting(QtGui.QCompleter.CaseInsensitivelySortedModel)

这里发生了什么?

4

1 回答 1

0

嗯...我不知道这是否是个好主意,但是如果我将所有顶级节点放在一个虚拟节点下,那么只有虚拟节点在完成期间会获得“无用”查询。

https://gist.github.com/jason-s/6c9495e29a4caac7ddf5cd739550a310#file-qtcompleter5b-py

我对 qtcompleter5.py 所做的更改:

  • 标题项是一个单独的项,不用作根
  • 虚拟节点返回""完成列的内容DisplayRole
  • QCompleter.splitPath 返回的路径前面有一个额外的虚拟组件
  • pathFromIndex()如果它是根节点,则忽略 的第一个组件
  • 在 AbstractItemModel 中:
    • rowCount()为无效的父级返回 1
    • parent()QtCore.QModelIndex()当提供的索引位于根时返回无效(以前是索引的父级位于根时)
    • index()当提供的父项无效时返回根项(以前它查找根项的适当子项)

这使得这个模型的 TreeView 看起来有点滑稽,但对于不需要 TreeView 的应用程序,它似乎工作正常;如果我输入United States/Arizona/P,那么它会打印:

splitPath:  ['', u'United States', u'Arizona', u'P']

Peoria
Peoria
Phoenix
Peoria
Peoria
Peoria
Peoria
Phoenix
Phoenix
于 2019-09-17T23:11:16.063 回答