【问题标题】:QComboBox with autocompletion works in PyQt4 but not in PySide具有自动完成功能的 QComboBox 在 PyQt4 中有效,但在 PySide 中无效
【发布时间】:2014-06-27 16:16:59
【问题描述】:

我有一个带有自定义完成器的组合框,它在 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_())

【问题讨论】:

    标签: python pyqt pyside qcompleter


    【解决方案1】:

    我在写问题的时候想出来了……

    看起来虽然PySide QCompleter documentation 列出了一个使用模型和父级初始化 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_())
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-25
    • 1970-01-01
    • 1970-01-01
    • 2017-04-24
    • 1970-01-01
    • 2020-11-04
    相关资源
    最近更新 更多