0

フィルタリングされた結果のリスト選択が存在しない場合、最初の項目を自動的に強調表示したいと思います。force_selection()何も選択されていない場合に最初のアイテムを強調表示するメソッドを作成しました。を使用しQListView.selectionModel()て選択インデックスを決定しています。スロットに接続しようとforce_selection()しました:と. ただし、textChanged とプロキシの更新の間にタイミングの問題があるようです。選択が行われることもあれば、選択が消えることもあります。QLineEdittextEdited(QString)textChanged(QString)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呼び出しの順序です。最初に接続textChangedするforce_selectionので、最初に呼び出されます。ただし、その時点では、フィルターは処理されず、プロキシは更新されません。そのため、フィルタリングによってすぐに削除される可能性のあるアイテムを選択します。

connect呼び出しの順序を入れ替えるだけです。

ところで、 のロジックを再考することをお勧めしますforce_selectioncurrentIndex必ずしも選択したインデックスに対応するとは限りません。と入力red2して削除することで確認できます2。あなたは両方Red1を取得し、Red2選択されます。の代わりにcurrentIndex使用して対処したい場合。選択したインデックスを処理する場合、条件はまたはに基づいている必要があります。setCurrentIndexselectselectedRowsselectedIndexes

于 2013-04-27T18:27:52.267 に答える