0

如果过滤结果不存在列表选择,那么我想自动突出显示第一项。我创建了方法force_selection()突出显示第一项的方法。我正在使用QListView.selectionModel()来确定选择索引。我已经尝试连接force_selection()QLineEdit插槽:textEdited(QString)textChanged(QString). 但是,在 textChanged 和代理刷新QListView. 有时会做出选择,而有时会消失。

那么,如果用户尚未做出选择,我将如何在代理过滤器期间强制选择(蓝色突出显示)?我的代码背后的想法是用户搜索一个项目,顶部的项目是最好的结果,所以它被选中(除非他们在过滤视图中手动选择另一个项目)。

您可以在此处找到问题的图像。

重新创建问题:

  1. 使用 Python 2.7 执行示例脚本
  2. 不要选择列表中的任何内容(QLineEdit 应该有焦点)
  3. 搜索'Red2',慢慢输入'R'、'e'、'd' --> Red1 和 Red2 可见,Red1 突出显示
  4. 通过键入数字“2”完成搜索-> Red2 不再突出显示/选择

最终解决方案:

    from PySide import QtCore
    from PySide import QtGui

    class SimpleListModel(QtCore.QAbstractListModel):

        def __init__(self, contents):
            super(SimpleListModel, self).__init__()
            self.contents = contents

        def rowCount(self, parent):
            return len(self.contents)

        def data(self, index, role):
            if role == QtCore.Qt.DisplayRole:
                return str(self.contents[index.row()])

    class Window(QtGui.QWidget):

        def __init__(self, parent=None):
            super(Window, self).__init__(parent)

            data = ['Red1', 'Red2', 'Blue', 'Yellow']
            self.model = SimpleListModel(data)

            self.view = QtGui.QListView(self)

            self.proxy = QtGui.QSortFilterProxyModel(self)
            self.proxy.setSourceModel(self.model)
            self.proxy.setDynamicSortFilter(True)
            self.proxy.setFilterCaseSensitivity(QtCore.Qt.CaseInsensitive)
            self.view.setModel(self.proxy)

            self.search = QtGui.QLineEdit(self)
            self.search.setFocus()

            layout = QtGui.QGridLayout()
            layout.addWidget(self.search, 0, 0)
            layout.addWidget(self.view, 1, 0)

            self.setLayout(layout)

            # Connect search to proxy model
            self.connect(self.search, QtCore.SIGNAL('textChanged(QString)'), 
                         self.proxy.setFilterFixedString)

            # Moved after connect for self.proxy.setFilterFixedString
            self.connect(self.search, QtCore.SIGNAL('textChanged(QString)'), 
                         self.force_selection)

            self.connect(self.search, QtCore.SIGNAL('returnPressed()'), 
                         self.output_index)

        # @QtCore.Slot(QtCore.QModelIndex)
        @QtCore.Slot(str)
        def force_selection(self, ignore):
            """ If user has not made a selection, then automatically select top item.
            """
            selection_model = self.view.selectionModel()
            indexes = selection_model.selectedIndexes()

            if not indexes:
                index = self.proxy.index(0, 0)
                selection_model.select(index, QtGui.QItemSelectionModel.Select)

        def output_index(self):
            print 'View Index:',self.view.currentIndex().row()
            print 'Selected Model Current Index:',self.view.selectionModel().currentIndex()
            print 'Selected Model Selected Index:',self.view.selectionModel().selectedIndexes()


    if __name__ == '__main__':
        import sys

        app = QtGui.QApplication(sys.argv)
        window = Window()
        window.show()
        sys.exit(app.exec_())
4

1 回答 1

1

问题是connect调用的顺序。你先连接textChangedforce_selection所以它首先被调用。但那时,过滤器没有处理,代理也没有更新。因此,您选择了一个可能很快会被过滤删除的项目。

只需切换connect调用顺序。

顺便说一句,你可能想重新考虑你的逻辑force_selectioncurrentIndex不一定对应于选定的索引。您可以通过键入red2和删除来观察这一点2。您将同时获得Red1并被Red2选中。如果你想处理currentIndexusesetCurrentIndex而不是select. 如果要处理选定的索引,则条件应基于selectedRowsor selectedIndexes

于 2013-04-27T18:27:52.267 回答