2013-04-24 78 views
0

如果篩選結果不存在列表選擇,則我想自動突出顯示第一個項目。我創建了方法force_selection(),如果沒有選擇任何內容,則突出顯示第一項。我正在使用QListView.selectionModel()來確定選擇索引。我試圖將force_selection()連接到QLineEdit插槽:textEdited(QString)textChanged(QString)。但是,似乎在textChanged和代理刷新QListView之間存在計時問題。有時選擇是在其他時間消失的情況下進行的。使用QSortFilterProxyModel進行過濾時,突出顯示/選擇QListView中的第一個可見項目

那麼,如果用戶還沒有做出選擇,那麼如何在代理過濾器中強制選擇(藍色突出顯示)呢?我的代碼背後的想法是用戶搜索一個項目,頂部項目是最好的結果,所以它被選中(除非他們手動選擇過濾器視圖中的另一個項目)。

You can find an image of the problem here.

重新創建問題:

  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_()) 
+0

更新後的鏈接截圖:http://imgur.com/PQq3knb – 2014-08-27 22:03:42

回答

1

的問題是connect呼叫的順序。您首先連接textChangedforce_selection,因此它首先被調用。但是那個時候,過濾器沒有被處理,代理服務器也沒有被更新。所以你選擇一個可能很快被過濾掉的項目。

只需切換connect調用的順序。

順便說一句,你可能想重新考慮你的邏輯force_selectioncurrentIndex不一定對應於選定的索引。您可以觀察到,輸入red2並刪除2。您將同時選中Red1Red2。如果你想處理currentIndex使用setCurrentIndex而不是select。如果你想處理選定的索引,那麼你的條件應該基於selectedRowsselectedIndexes

+0

謝謝!我更新了代碼以反映您的建議。我不知道連接呼叫的順序影響了行爲。 – 2013-04-29 18:25:56

相關問題