[英]QComboBox with autocompletion works in PyQt4 but not in PySide
I've got a combo box with a custom completer that worked fine in PyQt4, but isn't working in PySide. 我有一个带有自定义完成程序的组合框,它在PyQt4中可以正常工作,但在PySide中不起作用。
I have verified that the new completer is replacing the QComboBox's built in completer because inline completion is no longer occurring. 我已验证新的完成程序正在替换QComboBox的内置完成程序,因为不再发生内联完成。 However when run with PySide, the completer doesn't popup with a filtered list of options.
但是,当与PySide一起运行时,完成程序不会弹出带有选项过滤列表的弹出窗口。
I've also tried ensuring that all text is all str
or all unicode
to avoid differences between the PyQt API 1 with QStrings and PySide's use of Python unicode types. 我还尝试确保所有文本均为
str
或所有unicode
以避免带有QStrings的PyQt API 1与PySide使用Python unicode类型之间的差异。 Changing the text types has had no effect on either PyQt or PySide's behavior (PyQt keeps working, PySide doesn't work). 更改文本类型对PyQt或PySide的行为均没有影响(PyQt保持工作,PySide不工作)。
Here is my code: 这是我的代码:
from PySide import QtCore
from PySide import QtGui
#from PyQt4 import QtCore
#from PyQt4 import QtGui
class AdvComboBox(QtGui.QComboBox):
def __init__(self, parent=None):
super(AdvComboBox, self).__init__(parent)
self.setFocusPolicy(QtCore.Qt.StrongFocus)
self.setEditable(True)
# add a filter model to filter matching items
self.pFilterModel = QtGui.QSortFilterProxyModel(self)
self.pFilterModel.setFilterCaseSensitivity(QtCore.Qt.CaseInsensitive)
self.pFilterModel.setSourceModel(self.model())
# add a completer, which uses the filter model
self.completer = QtGui.QCompleter(self.pFilterModel, self)
# always show all (filtered) completions
self.completer.setCompletionMode(QtGui.QCompleter.UnfilteredPopupCompletion)
self.setCompleter(self.completer)
# connect signals
def filter(text):
print "Edited: ", text, "type: ", type(text)
self.pFilterModel.setFilterFixedString(str(text))
self.lineEdit().textEdited[unicode].connect(filter)
self.completer.activated.connect(self.on_completer_activated)
# on selection of an item from the completer, select the corresponding item from combobox
def on_completer_activated(self, text):
print "activated"
if text:
print "text: ", text
index = self.findText(str(text))
print "index: ", index
self.setCurrentIndex(index)
# on model change, update the models of the filter and completer as well
def setModel(self, model):
super(AdvComboBox, self).setModel(model)
self.pFilterModel.setSourceModel(model)
self.completer.setModel(self.pFilterModel)
# on model column change, update the model column of the filter and completer as well
def setModelColumn(self, column):
self.completer.setCompletionColumn(column)
self.pFilterModel.setFilterKeyColumn(column)
super(AdvComboBox, self).setModelColumn(column)
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
combo = AdvComboBox()
names = ['bob', 'fred', 'bobby', 'frederick', 'charles', 'charlie', 'rob']
# fill the standard model of the combobox
combo.addItems(names)
combo.setModelColumn(0)
combo.resize(300, 40)
combo.show()
sys.exit(app.exec_())
I figured it out while writing the question... 我在写问题时想通了...
It appears that while the PySide QCompleter documentation lists an option to initialize the QCompleter with a model and a parent, it isn't actually working. 看起来,虽然PySide QCompleter文档列出了使用模型和父级初始化QCompleter的选项,但实际上并没有用。
The solution is to set the model of the completer after it is initialized. 解决方案是在初始化完成程序后设置其模型。
Here is the working code: 这是工作代码:
from PySide import QtCore
from PySide import QtGui
class AdvComboBox(QtGui.QComboBox):
def __init__(self, parent=None):
super(AdvComboBox, self).__init__(parent)
self.setFocusPolicy(QtCore.Qt.StrongFocus)
self.setEditable(True)
# add a filter model to filter matching items
self.pFilterModel = QtGui.QSortFilterProxyModel(self)
self.pFilterModel.setFilterCaseSensitivity(QtCore.Qt.CaseInsensitive)
self.pFilterModel.setSourceModel(self.model())
# add a completer
self.completer = QtGui.QCompleter(self)
#Set the model that the QCompleter uses
# - in PySide doing this as a separate step worked better
self.completer.setModel(self.pFilterModel)
# always show all (filtered) completions
self.completer.setCompletionMode(QtGui.QCompleter.UnfilteredPopupCompletion)
self.setCompleter(self.completer)
# connect signals
def filter(text):
print "Edited: ", text, "type: ", type(text)
self.pFilterModel.setFilterFixedString(str(text))
self.lineEdit().textEdited[unicode].connect(filter)
self.completer.activated.connect(self.on_completer_activated)
# on selection of an item from the completer, select the corresponding item from combobox
def on_completer_activated(self, text):
print "activated"
if text:
print "text: ", text
index = self.findText(str(text))
print "index: ", index
self.setCurrentIndex(index)
# on model change, update the models of the filter and completer as well
def setModel(self, model):
super(AdvComboBox, self).setModel(model)
self.pFilterModel.setSourceModel(model)
self.completer.setModel(self.pFilterModel)
# on model column change, update the model column of the filter and completer as well
def setModelColumn(self, column):
self.completer.setCompletionColumn(column)
self.pFilterModel.setFilterKeyColumn(column)
super(AdvComboBox, self).setModelColumn(column)
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
combo = AdvComboBox()
names = ['bob', 'fred', 'bobby', 'frederick', 'charles', 'charlie', 'rob']
# fill the standard model of the combobox
combo.addItems(names)
combo.setModelColumn(0)
combo.resize(300, 40)
combo.show()
sys.exit(app.exec_())
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.