如何让自定义QCompleter与自定义项委托一起工作?

2024-10-01 05:01:35 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个自定义qcompleter(匹配字符串的任何部分)和一个自定义QStyledItemDelegate(在qcompleter返回的下拉选项上显示不同的格式)应用于QLineEdit,它们都可以单独工作,但是当我同时应用它们时,QStyledItemDelegate不工作

import sys
from PySide2.QtWidgets import QApplication, QMainWindow, QLineEdit, QCompleter, QStyledItemDelegate
from PySide2.QtCore import Qt, QSortFilterProxyModel, QStringListModel
from PySide2.QtGui import QColor, QPalette

Qcompleter项目代表:

class CompleterItemDelegate(QStyledItemDelegate):
    def initStyleOption(self, option, index):
        super(CompleterItemDelegate, self).initStyleOption(option, index)
        option.backgroundBrush = QColor("red")
        option.palette.setBrush(QPalette.Text, QColor("blue"))
        option.displayAlignment = Qt.AlignCenter

自定义QCompleter:

class CustomQCompleter(QCompleter):
    def __init__(self, parent=None):
        super(CustomQCompleter, self).__init__(parent)
        self.local_completion_prefix = ""
        self.source_model = None

    def setModel(self, model):
        self.source_model = model
        super(CustomQCompleter, self).setModel(self.source_model)

    def updateModel(self):
        local_completion_prefix = self.local_completion_prefix
        class InnerProxyModel(QSortFilterProxyModel):
            def filterAcceptsRow(self, sourceRow, sourceParent):
                index0 = self.sourceModel().index(sourceRow, 0, sourceParent)
                searchStr = local_completion_prefix.lower()
                searchStr_list = searchStr.split()
                modelStr = self.sourceModel().data(index0,Qt.DisplayRole).lower()
                for string in searchStr_list:
                    if not string in modelStr:
                        return False
                return True

        proxy_model = InnerProxyModel()
        proxy_model.setSourceModel(self.source_model)
        super(CustomQCompleter, self).setModel(proxy_model)

    def splitPath(self, path):
        self.local_completion_prefix = str(path)
        self.updateModel()
        return ""

主要内容:

class MainWindow(QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()

        model = QStringListModel()
        model.setStringList(['Tom', 'Tommy Stevens', 'Steven'])

        # ITEM DELEGATE ONLY - WORKS
        # completer = QCompleter()
        # completer.setModel(model)
        # delegate = CompleterDelegate()
        # completer.popup().setItemDelegate(delegate)

        # QCOMPLETER DELEGATE ONLY - WORKS
        # completer = CustomQCompleter(self)
        # completer.setModel(model)

        # ITEM DELEGATE AND QCOMPLETER DELEGATE - ITEM DELEGATE DOESNT WORK
        completer = CustomQCompleter(self)
        completer.setModel(model)
        delegate = CompleterItemDelegate()
        completer.popup().setItemDelegate(delegate)

        self.lineEdit = QLineEdit()
        self.lineEdit.setCompleter(completer)

        self.setCentralWidget(self.lineEdit)
        self.show()

if __name__ == '__main__':
    app  = QApplication(sys.argv)
    p = MainWindow()
    p.show()
    sys.exit(app.exec_())
  1. 有没有办法让这段代码正常工作
  2. 是否有更好的方法来实现选择qcompleter的完成规则和格式化弹出结果

Tags: importselfprefixmodellocaldefcompletionoption
2条回答

如果随后设置了模型,则在弹出窗口上设置委托将不起作用,因为^{}也会调用^{},这反过来会设置new item delegate

因此,你可以:

  • 确保在完成器上设置模型后设置代理
  • 通过调用基本实现和然后还原委托,或者通过在基本实现调用之前还原委托,对完成符进行子类化并重写setModel();请注意,这在您的案例中不起作用,因为您在updateModel()中调用了基本实现,这将明显忽略覆盖

移动的

delegate = CompleterItemDelegate()
self.popup().setItemDelegate(delegate)

进入CustomQCompleter updateModel函数解决了musicamante指出的问题

相关问题 更多 >