问题
The PySide docs include this section on QCompleter with tree models:
PySide.QtGui.QCompleter can look for completions in tree models, assuming that any item (or sub-item or sub-sub-item) can be unambiguously represented as a string by specifying the path to the item. The completion is then performed one level at a time.
Let’s take the example of a user typing in a file system path. The model is a (hierarchical) PySide.QtGui.QFileSystemModel . The completion occurs for every element in the path. For example, if the current text is C:\Wind , PySide.QtGui.QCompleter might suggest Windows to complete the current path element. Similarly, if the current text is C:\Windows\Sy , PySide.QtGui.QCompleter might suggest System .
For this kind of completion to work, PySide.QtGui.QCompleter needs to be able to split the path into a list of strings that are matched at each level. For C:\Windows\Sy , it needs to be split as “C:”, “Windows” and “Sy”. The default implementation of PySide.QtGui.QCompleter.splitPath() , splits the PySide.QtGui.QCompleter.completionPrefix() using QDir.separator() if the model is a PySide.QtGui.QFileSystemModel .
To provide completions, PySide.QtGui.QCompleter needs to know the path from an index. This is provided by PySide.QtGui.QCompleter.pathFromIndex() . The default implementation of PySide.QtGui.QCompleter.pathFromIndex() , returns the data for the edit role for list models and the absolute file path if the mode is a PySide.QtGui.QFileSystemModel.
But I can't seem to find an example showing how to do this. Can anyone point me at an example I can use as a starting point? (In my investigation it looks like maybe the hard part is the tree model rather than the QCompleter)
It looks like you would need to provide these functions:
- ability to split a string into segments (for the example given,
C:\Windows\Sy
to['C:','Windows','Sy']
- the ability to specify the list of items that include the last segment (e.g. all the items included in
['C:','Windows']
I found an example for the basic functionality of QCompleter and have been able to tweak the basics fine (see below), I just don't know how to go about implementing a tree model type application.
'''based on
http://codeprogress.com/python/libraries/pyqt/showPyQTExample.php?index=403&key=QCompleterQLineEdit'''
from PySide.QtGui import *
from PySide.QtCore import *
import sys
def main():
app = QApplication(sys.argv)
edit = QLineEdit()
strList = '''
Germany;Russia;France;
french fries;frizzy hair;fennel;fuzzball
frayed;fickle;Frobozz;fear;framing;frames
Franco-American;Frames;fancy;fire;frozen yogurt
football;fnord;foul;fowl;foo;bar;baz;quux
family;Fozzie Bear;flinch;fizzy;famous;fellow
friend;fog;foil;far;flower;flour;Florida
'''.replace('\n',';').split(";")
strList.sort(key=lambda s: s.lower())
completer = QCompleter(strList,edit)
completer.setCaseSensitivity(Qt.CaseInsensitive)
edit.setWindowTitle("PySide QLineEdit Auto Complete")
edit.setCompleter(completer)
edit.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
回答1:
I couldn't find a good example for what I wanted, but I figured out how to adapt the Qt TreeModel example to using a QCompleter:
https://gist.github.com/jason-s/9dcef741288b6509d362
The QCompleter is the easy part, you just have to tell it how to split a path into segments, and then how to get from a particular entry in the model back to a path:
class MyCompleter(QtGui.QCompleter):
def splitPath(self, path):
return path.split('/')
def pathFromIndex(self, index):
result = []
while index.isValid():
result = [self.model().data(index, QtCore.Qt.DisplayRole)] + result
index = index.parent()
r = '/'.join(result)
return r
Aside from that, you have to configure the QCompleter properly, telling it how to get from a model item to a text string. Here I set it up to use the DisplayRole and to use column 0.
edit = QtGui.QLineEdit()
completer = MyCompleter(edit)
completer.setModel(model)
completer.setCompletionColumn(0)
completer.setCompletionRole(QtCore.Qt.DisplayRole)
completer.setCaseSensitivity(QtCore.Qt.CaseInsensitive)
回答2:
As the documentation for QCompleter says you can provide two models: a list model or a tree model.
Example for list model, after your example:
from PySide import QtGui
app = QtGui.QApplication([])
edit = QtGui.QLineEdit()
strList = "Germany;Russia;France;Norway".split(";")
completer = QtGui.QCompleter(strList)
edit.setCompleter(completer)
edit.show()
app.exec_()
works:
And as a tree model:
from PySide import QtGui, QtCore
app = QtGui.QApplication([])
edit = QtGui.QLineEdit()
model = QtGui.QFileSystemModel()
model.setFilter(QtCore.QDir.AllDirs | QtCore.QDir.Drives)
model.setRootPath('')
completer = QtGui.QCompleter(model, edit)
edit.setCompleter(completer)
edit.show()
app.exec_()
for some strange reason nothing is displayed here. Will investigate later.
来源:https://stackoverflow.com/questions/24687620/looking-for-example-for-qcompleter-with-segmented-completion-tree-models