【问题标题】:PySide2 AutoComplete: Customize the ResultPySide2 自动完成:自定义结果
【发布时间】:2021-11-20 00:09:42
【问题描述】:

我正在使用 QCompleter 在 QLineEdit 小部件上实现自动完成:

from PySide2 import QtGui
from PySide2.QtCore import Qt
from PySide2.QtGui import QStandardItem
from PySide2.QtWidgets import QCompleter, QWidget, QLineEdit, QFormLayout, QApplication


class SuggestionPlaceModel(QtGui.QStandardItemModel):

    def __init__(self, parent=None):
        super(SuggestionPlaceModel, self).__init__(parent)

    def search(self, text):
        self.clear()
        data = [{'text': f"{text} {i}"} for i in range(10)]
        for i, row in enumerate(data):
            item = QStandardItem(row['text'])
            self.appendRow(item)


class Completer(QCompleter):

    def splitPath(self, path):
        self.model().search(path)
        return super(Completer, self).splitPath(path)


class Widget(QWidget):

    def __init__(self, parent=None):
        super(Widget, self).__init__(parent)
        self._model = SuggestionPlaceModel(self)
        completer = Completer(self)
        completer.setCaseSensitivity(Qt.CaseInsensitive)
        completer.setModel(self._model)
        lineedit = QLineEdit()
        lineedit.setCompleter(completer)
        lay = QFormLayout(self)
        lay.addRow("Location: ", lineedit)


if __name__ == '__main__':

    import sys

    app = QApplication(sys.argv)
    w = Widget()
    w.show()
    sys.exit(app.exec_())

这是一个结果:

问题:如何自定义SuggestionPlaceModel 类,以便搜索结果可以包括图标、水平分隔符、不同的字体、不同的字体大小等?

【问题讨论】:

  • 可以使用 setIcon() 为 QStandardItemModel 设置每个项目的图标。不同的字体和间距是完全不同的,而且肯定要困难得多,因为您需要使用自定义的delegate(可能是QStyledItemDelegate)设置带有setPopup 的自定义QListView,同时覆盖sizeHint() 和@987654334 @方法。

标签: python autocomplete pyqt5 pyside2


【解决方案1】:

一种可能的解决方案是在设置图标的地方使用自定义委托,对于 html,您可以使用支持富文本的 QLabel。

import random
from PySide2 import QtCore, QtGui, QtWidgets


class Delegate(QtWidgets.QStyledItemDelegate):
    def initStyleOption(self, option, index):
        super(Delegate, self).initStyleOption(option, index)
        option.text = ""

    def paint(self, painter, option, index):
        if isinstance(option.widget, QtWidgets.QAbstractItemView):
            option.widget.openPersistentEditor(index)
        super(Delegate, self).paint(painter, option, index)

    def createEditor(self, parent, option, index):
        editor = QtWidgets.QLabel(index.data(), parent)
        editor.setContentsMargins(0, 0, 0, 0)
        editor.setText(index.data(QtCore.Qt.UserRole))
        return editor


class SuggestionPlaceModel(QtGui.QStandardItemModel):
    def search(self, text):
        self.clear()
        for i in range(10):
            html = f"{text}-{i} <b>Stack</b> <i>Overflow</i>"
            plain = QtGui.QTextDocumentFragment.fromHtml(html).toPlainText()
            pixmap = QtGui.QPixmap(128, 128)
            pixmap.fill(QtGui.QColor(*random.sample(range(255), 4)))
            item = QtGui.QStandardItem(plain)
            item.setData(html, QtCore.Qt.UserRole)
            item.setIcon(QtGui.QIcon(pixmap))
            self.appendRow(item)


class Completer(QtWidgets.QCompleter):
    def splitPath(self, path):
        self.model().search(path)
        return super(Completer, self).splitPath(path)


class Widget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(Widget, self).__init__(parent)
        self._model = SuggestionPlaceModel(self)
        completer = Completer(self)
        completer.setCaseSensitivity(QtCore.Qt.CaseInsensitive)
        completer.setModel(self._model)
        delegate = Delegate(completer.popup())
        completer.popup().setItemDelegate(delegate)

        lineedit = QtWidgets.QLineEdit()
        lineedit.setCompleter(completer)
        lay = QtWidgets.QFormLayout(self)
        lay.addRow("Location: ", lineedit)


if __name__ == "__main__":

    import sys

    app = QtWidgets.QApplication(sys.argv)
    w = Widget()
    w.show()
    sys.exit(app.exec_())

【讨论】:

  • 太棒了!准确答案!
  • 顺便说一句,当 lineedit 小部件聚焦时关键字为空,如何显示结果?尝试过 completor.complete() 但没有运气...
猜你喜欢
  • 2011-09-08
  • 1970-01-01
  • 2013-07-10
  • 2011-12-06
  • 1970-01-01
  • 2011-01-27
  • 1970-01-01
  • 2012-03-07
  • 2011-01-04
相关资源
最近更新 更多