python - 如何让自定义 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_())
- 有没有办法让这段代码工作?
- 有没有更好的方法来实现为 qcompleter 选择完成规则和格式化弹出结果?
解决方案
如果模型是在之后设置的,那么在弹出窗口上设置委托将不起作用,因为setModel()
还会调用setPopup()
,这反过来又会设置一个新的项目委托。
所以,你要么:
- 确保在完成者上设置模型后设置委托;
setModel()
通过调用基本实现然后恢复委托,或complete()
通过在基本实现调用之前恢复委托,子类化完成者和覆盖;请注意,这在您的情况下不起作用,因为您调用了基本实现,updateModel()
其中显然会忽略覆盖;
推荐阅读
- vb.net - 是否可以在设计时更改属性属性的值?
- azure - 无法通过公共 IP 访问部署在 Azure Kubernetes 服务上的服务
- mysql - MYSQL - 加入 2 个表 - 及时排序
- docker - 无法从 Mesos UI 跟踪“沙盒”链接
- ldap - 处理报表门户中 LDAP 用户的项目和成员角色的自动分配
- javascript - V-for 显示对象的特定属性
- python - 有人可以解释为什么会编译吗?
- javascript - 如何捕获用户自己进行的手动下拉更改?
- typescript - 接口不适合时打字稿编译器的奇怪行为
- java - 无法在 Spring Boot 中解析模型级别的属性文件中的消息