如何获得自定义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, 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和格式化弹出结果?

如果之后设置模型,则在弹出窗口上设置委托将不起作用,因为setModel()也调用setPopup(),这反过来又设置了一个新的项目委托。

所以,你要么:

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

移动

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

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

最新更新