Ищем пример для QCompleter с сегментированными моделями завершения / дерева
Документы PySide включают этот раздел в QCompleter с древовидными моделями:
PySide.QtGui.QCompleter может искать дополнения в древовидных моделях, предполагая, что любой элемент (или подпункт, или подподпункт) может быть однозначно представлен в виде строки, указав путь к элементу. Завершение затем выполняется по одному уровню за раз.
Давайте рассмотрим пример, когда пользователь вводит путь к файловой системе. Модель представляет собой (иерархическую) PySide.QtGui.QFileSystemModel . Завершение происходит для каждого элемента в пути. Например, если текущим текстом является C:\Wind, PySide.QtGui.QCompleter может предложить Windows завершить текущий элемент пути. Аналогичным образом, если текущий текст - C:\Windows\Sy, PySide.QtGui.QCompleter может предложить Систему.
Чтобы этот вид завершения работал, 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()
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)
Как сказано в документации для 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_()
по какой-то странной причине здесь ничего не отображается. Будем расследовать позже.