ищем, например, QCompleter с сегментированными моделями завершения/дерева

Документы PySide включают этот раздел в QCompleter с древовидными моделями:

PySide.QtGui.QCompleter может искать завершения в древовидных моделях, предполагая, что любой элемент (или подэлемент или подподэлемент) можно однозначно представить в виде строки, указав путь к элементу. Затем завершение выполняется по одному уровню за раз.

Давайте возьмем пример пользователя, который вводит путь к файловой системе. Модель представляет собой (иерархическую) PySide.QtGui.QFileSystemModel . Завершение происходит для каждого элемента пути. Например, если текущий текст C:\Wind , PySide.QtGui.QCompleter может предложить Windows завершить текущий элемент пути. Точно так же, если текущий текст C:\Windows\Sy , PySide.QtGui.QCompleter может предложить System .

Чтобы такое завершение работало, PySide.QtGui.QCompleter должен уметь разбивать путь на список строк, совпадающих на каждом уровне. Для C:\Windows\Sy его необходимо разделить на «C:», «Windows» и «Sy». Реализация PySide.QtGui.QCompleter.splitPath() по умолчанию разделяет PySide.QtGui.QCompleter.completionPrefix() с помощью QDir.separator(), если модель является PySide.QtGui.QFileSystemModel.

Чтобы обеспечить завершение, PySide.QtGui.QCompleter должен знать путь из индекса. Это обеспечивается PySide.QtGui.QCompleter.pathFromIndex() . Реализация PySide.QtGui.QCompleter.pathFromIndex() по умолчанию возвращает данные для роли редактирования для моделей списков и абсолютный путь к файлу, если используется режим PySide.QtGui.QFileSystemModel.

Но я не могу найти пример, показывающий, как это сделать. Может ли кто-нибудь указать мне пример, который я могу использовать в качестве отправной точки? (В моем расследовании похоже, что трудной частью является древовидная модель, а не QCompleter)

Похоже, вам нужно будет предоставить эти функции:

  • возможность разбить строку на сегменты (в данном примере от C:\Windows\Sy до ['C:','Windows','Sy']
  • возможность указать список элементов, включающих последний сегмент (например, все элементы, включенные в ['C:','Windows']

Я нашел пример базовой функциональности QCompleter и смог хорошо настроить основы (см. Ниже), я просто не знаю, как реализовать приложение типа древовидной модели.

'''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()

person Jason S    schedule 10.07.2014    source источник
comment
Возможно, поможет этот пример из документации Qt.   -  person doru    schedule 11.07.2014
comment
Я уже нашел это, но я действительно запутался в том, как сделать модель дерева.   -  person Jason S    schedule 11.07.2014


Ответы (2)


Я не смог найти хороший пример того, что хотел, но я понял, как адаптировать пример Qt TreeModel к использованию QCompleter:

https://gist.github.com/jason-s/9dcef741288b6509d362

введите здесь описание изображения

QCompleter — это простая часть, вам просто нужно сказать ему, как разбить путь на сегменты, а затем как вернуться от определенной записи в модели к пути:

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

Кроме того, вы должны правильно настроить QCompleter, указав ему, как перейти от элемента модели к текстовой строке. Здесь я настроил его для использования DisplayRole и столбца 0.

edit     = QtGui.QLineEdit()
completer     = MyCompleter(edit)
completer.setModel(model)
completer.setCompletionColumn(0)
completer.setCompletionRole(QtCore.Qt.DisplayRole)
completer.setCaseSensitivity(QtCore.Qt.CaseInsensitive)    
person Jason S    schedule 13.07.2014

В качестве документации для QCompleter говорит, что вы можете предоставить две модели: модель списка или модель дерева.

Пример для модели списка после вашего примера:

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_()

работает:

введите здесь описание изображения

И как модель дерева:

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_()

по какой-то странной причине здесь ничего не отображается. Расследует позже.

person Trilarion    schedule 11.07.2014
comment
Спасибо... проблема не только в QCompleter, а в том, как сделать саму модель дерева. (QFileSystemModel великолепен, но он не помогает мне инкапсулировать мои иерархические данные таким образом, чтобы это было совместимо с QCompleter) - person Jason S; 11.07.2014