0

I was looking to select a row in a QTreeView programmatically, and I found 95% of the answer here.

The select() method does the job perfectly, except that it doesn't seem to trigger any of the events of clicking on the view.

I found a workaround by calling the needed signal myself - but are there any hints of a method that would emulate a human click and send all the signals associated?

Here's my workaround (in Python) :

oldIndex=treeView.selectionModel().currentIndex()
newIndex=treeView.model().indexFromItem(item)
#indexes stored----------------------------------
treeView.selectionModel().select(
    newIndex,
    QtGui.QItemSelectionModel.ClearAndSelect)
#selection changed-------------------------------
treeView.selectionModel().currentRowChanged.emit(
    newIndex,
    oldIndex)
#signal manually emitted-------------------------
Community
  • 1
  • 1
gui3
  • 1,711
  • 14
  • 30
  • 1
    What specific associated signals are you referrring to? – ekhumoro Nov 15 '16 at 17:04
  • 1
    @ekhumoro Probably the selectionChanged signal. However that should actually have been emitted, shouldn't it? – NoDataDumpNoContribution Nov 16 '16 at 08:34
  • in fact i needed the currentRowChanged signal so the hack works in my case but i was wondering if there was any way of imitating a human click and ALL signals that comes from that. – gui3 Nov 16 '16 at 09:13
  • By the way i can't figure what does selectionChange do. Interested by it y tried to connect it instead of currentRowChanged but as the doc says it is not a signal but a slot. do you think i can use it to actually change the selection ? – gui3 Nov 16 '16 at 09:15
  • 1
    @Gui3. I think @Trilarion means [treeView.selectionModel().selectionChanged](http://doc.qt.io/qt-4.8/qitemselectionmodel.html#selectionChanged). However, it is not quite the same as `currentChanged`, because it passes `QItemSelection` objects, rather than indexes. – ekhumoro Nov 16 '16 at 19:04
  • Thanks! I made a typing error, I meant selectionChanged, and I must have made another error trying to use it as a signal and thinking it was a slot. selectionChanged is indeed a signal and is indeed send by the select() method, so listenning it instead of currentRowChanged avoids me to send the signal manually. I guess this is the easiest and closest way to imitate human clicking even if it still does not send all the same events ... – gui3 Nov 22 '16 at 10:54

1 Answers1

4

So thanks to the comments the answer was found in listenning to the selectionChanged() signal instead of the currentRowChanged(), since the first is sent by the select() method.

This required very few modifications:

#in the signal connections :__________________________________________
    #someWidget.selectionModel().currentRowChanged.connect(calledMethod)
    someWidget.selectionModel().selectionChanged.connect(calledMethod)

#in the called Method_________________________________________________
#selectionChanged() sends new QItemSelection and old QItemSelection
#where currentRowChanged() sent new QModelIndex and old QModelIndex
#these few lines allow to use both signals and to not change a thing
#in the remaining lines
def calledMethod(self,newIndex,oldIndex=None):
    try: #if qItemSelection
        newIndex=newIndex.indexes()[0]
    except: #if qModelIndex
        pass
    #..... the method has not changed further

#the final version of the programmatical select Method:_______________
def selectItem(self,widget,itemOrText):
    oldIndex=widget.selectionModel().currentIndex()
    try: #an item is given--------------------------------------------
        newIndex=widget.model().indexFromItem(itemOrText)
    except: #a text is given and we are looking for the first match---
        listIndexes=widget.model().match(widget.model().index(0, 0),
                          QtCore.Qt.DisplayRole,
                          itemOrText,
                          QtCore.Qt.MatchStartsWith)
        newIndex=listIndexes[0]
    widget.selectionModel().select( #programmatical selection---------
            newIndex,
            QtGui.QItemSelectionModel.ClearAndSelect)
gui3
  • 1,711
  • 14
  • 30
  • 1
    `if isinstance(QtGui.QItemSelection, newIndex): ...` – ekhumoro Nov 22 '16 at 20:18
  • yes this would be more accurate. I'm a try guy since I went from 20s to 0.5s by replacing an IF with a TRY in some loading function but I guess in this case there is no need for it – gui3 Nov 23 '16 at 09:43