Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
687 views
in Technique[技术] by (71.8m points)

qt - looking for example for QCompleter with segmented completion / tree models

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:WindowsSy , 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:WindowsSy , 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:WindowsSy 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('
',';').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()
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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

enter image description here

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)    

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...