我可以告诉你,首先,尝试将 QCompleter 包装在新功能周围是一个巨大的痛苦。您必须能够满足 QCompleter 的所有接口,并围绕该实时代码桥接它。
您必须手动更新 QCompleter 上设置的 QStringListModel,并为给定的搜索前缀提供获取当前完成和完成总数的实现。
这是一个与 PopupCompletion 模式兼容的工作示例:
import re
class ReadlineCompleter(QtGui.QCompleter):
def __init__(self, completeFn, *args, **kwargs):
super(ReadlineCompleter, self).__init__(*args, **kwargs)
self._completer = completeFn
self.setModel(QtGui.QStringListModel())
self.update()
def setCompletionPrefix(self, val):
super(ReadlineCompleter, self).setCompletionPrefix(val)
self.update()
def currentCompletion(self):
state = self.currentRow()
return self._completionAt(state)
def completionCount(self):
state = 0
while True:
result = self._completionAt(state)
if not result:
break
state += 1
return state
def update(self):
matches = [self._completionAt(i) for i in xrange(self.completionCount())]
self.model().setStringList(matches)
def _completionAt(self, state):
text = str(self.completionPrefix())
# regex to split on any whitespace, or the char set +*/^()-
match = re.match(r'^(.*)([\s+*/^()-]+)(.*)$', text)
if match:
prefix, sep, text = match.groups()
result = self._completer(str(text), state)
if result and match:
result = sep.join([prefix, result])
return '' if result is None else result
请注意,在该_completionAt()
方法中,我添加了您想要的额外功能,用于检测分隔符模式。你可以很明显地调整它。但它会拆分最后一部分并使用该值来检查完成,然后再次使用前缀重新加入结果。
用法
重要的。您需要将textChanged
来自 QLineEdit 的信号连接到完成器以强制更新。否则,完成程序中不会使用任何功能。
line = QtGui.QLineEdit()
comp = ReadlineCompleter(completer)
comp.setCompletionMode(comp.PopupCompletion)
line.setCompleter(comp)
# important
line.textChanged.connect(comp.setCompletionPrefix)
这里有一些例子展示了其他人如何在自定义行编辑中填写功能,他们完全绕过完成者的标准信号并自己触发它。你可以看到它的一点点努力。