微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

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

我有一个自定义的 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,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 选择完成规则和格式化弹出结果?

解决方法

如果模型是在之后设置的,则在弹出窗口上设置委托将不起作用,因为 setModel() 还会调用 setPopup(),后者又会设置一个 new item delegate

所以,你要么:

  • 确保在完成器上设置模型之后设置委托;
  • 子类化完成器并覆盖 setModel(),方法是调用基本实现,然后然后恢复委托,或者 complete() 通过恢复委托 before基本实现调用;请注意,这在您的情况下不起作用,因为您在 updateModel() 中调用了基本实现,这显然会忽略覆盖;
,

移动

props.history.push('/')

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。