带有自动补全功能的QComboBox在PyQt4中工作,但在PySide中不工作



我有一个带有自定义补全器的组合框,在PyQt4中工作良好,但在PySide中不起作用。

我已经验证了新的补全器正在取代QComboBox的内置补全器,因为内联补全不再发生。但是,当使用PySide运行时,补全器不会弹出一个过滤后的选项列表。

我还尝试确保所有文本都是所有str或所有unicode,以避免PyQt API 1与QStrings和PySide使用Python unicode类型之间的差异。更改文本类型对PyQt或PySide的行为没有影响(PyQt保持工作,PySide不工作)。

下面是我的代码:
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_())

我是在写问题的时候想到的…

虽然PySide QCompleter文档列出了一个使用模型和父类初始化QCompleter的选项,但它实际上不起作用。

解决方法是初始化完全机后设置模型。

下面是工作代码:
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_())

相关内容

  • 没有找到相关文章

最新更新