Why would currentIndex() return an index, but selectedIndexes() return an empty list?



  • I have two lines of code;
    @QModelIndex temp = selectionModel->currentIndex();
    QModelIndexList list = selectionModel->selectedIndexes();@
    After running, temp is a QModelIndex item, but the list is empty. I was expecting the list to contain a single index (the same index as temp). Why's the list empty?



  • Hi,

    the doc says:
    void QItemSelectionModel::setCurrentIndex ( const QModelIndex & index, QItemSelectionModel::SelectionFlags command ) [slot]
    Sets the model item index to be the current item, and emits currentChanged(). The current item is used for keyboard navigation and focus indication; it is independent of any selected items, although a selected item can also be the current item.

    Depending on the specified command, the index can also become part of the current selection.



  • I don't understand; I'm not calling setCurrentIndex.



  • I'm now... quite confused :(

    This is a big lot of code that I didn't write and the original team of programmers are unavailable. I've been digging through, and I found that there is a call to setCurrentIndex, whenever the user clicks on a line in the QTreeView. It contains the following code which is called when the signal currentChanged is emitted by the selection model:

    @ auto sourceIndex = componentMessageModel->mapToSource(index);
    sourceSelectionModel->setCurrentIndex(sourceIndex, QItemSelectionModel::ClearAndSelect);@

    So it looks like when the user clicks on any given line, the sourceSelectionModel is deliberately cleared (i.e. the selection is set to no selection by the ClearAndSelect) and then this one single index is selected. To test this theory, I did the following:
    @ auto sourceIndex = componentMessageModel->mapToSource(index);
    sourceSelectionModel->setCurrentIndex(sourceIndex, QItemSelectionModel::ClearAndSelect);
    auto list = sourceSelectionModel->selectedIndexes();@
    I thought I'd see that list contained a single item. It doesn't. It's empty. Nothing in it.

    So then I thought I'd change that QItemSelectionModel::ClearAndSelect, so I changed to code to this:
    @ auto sourceIndex = componentMessageModel->mapToSource(index);
    sourceSelectionModel->setCurrentIndex(sourceIndex, QItemSelectionModel::Select);
    auto list = sourceSelectionModel->selectedIndexes();@
    and list is still blank, so then I tried this:
    @auto sourceIndex = componentMessageModel->mapToSource(index);
    sourceSelectionModel->setCurrentIndex(sourceIndex, QItemSelectionModel::Current);
    sourceSelectionModel->select(sourceIndex, QItemSelectionModel::SelectCurrent);
    auto list = sourceSelectionModel->selectedIndexes();@
    and NOW the list does contain something; it contains one item, the current item.

    I was under the impression that the "selection" was essentially whatever the user had highlighted by clicking on the QTreeView window. My experiments above seem to indicate that actually the selection is something I'll have to update myself, manually, each time the user clicks on something. This makes little sense to me; the selectionModel is emitting the signal that the current item has changed, and for me to then have to manually tell the selectionModel what is currently selected seems crazy, and I'd have no way to tell it that there are multiple items in the selection. While all this is going on, the QTreeView happily lets me highlight multiple items by CTRL-LEFT-CLICK, even though none of them seem to end up in the selection.

    Can anyone explain to me what's going on? Is the selectionModel of the QTreeView supposed to keep track itself of what is currently selected?


  • Moderators

    there is a difference between "current" and "selection".
    There can only be on single current index at the time. This is the index with the dotted frame.
    The selection is more or less independent of the current index.



  • I can't seem to get a clear answer to this question; is there a permanent, irrevocable link between what the user can see is "selected" in the tree view on the screen (i.e. the lines they highlight by clicking on them with CTRL-LEFT-CLICK) and what should be returned by @auto list = sourceSelectionModel->selectedIndexes();@

    At the moment, it seems that clicking things on the screen doesn't actually affect what is returned by @auto list = sourceSelectionModel->selectedIndexes();@



  • QTreeView is supposed to do what everything you expect from it ...

    you easy can check it, by connecting the signal clicked(QModelIndex) to a slot, like:

    @void Foo::slotOnClick( const QModelIndex & index )
    {
    QTreeView treeView = (QTreeView)sender();

    if(treeView)
    {
        int r = index.row();
        int c = index.column();
    
        int r1 = treeView->selectionModel()->currentIndex().row();
        int c1 = treeView->selectionModel()->currentIndex().column();
    
        QModelIndexList list = treeView->selectionModel()->selectedIndexes();
    }
    

    }@

    disable your code to not touch anything ...
    and view.setSelectionMode(QAbstractItemView::ExtendedSelection);

    I have just tested and everything is as expected: clicked item gets the current one, and multiple selected(highlighted) go to the selection

    and, btw your working code is still messed up since:

    instead
    @ sourceSelectionModel->select(sourceIndex, QItemSelectionModel::SelectCurrent);@

    should be

    @ sourceSelectionModel->select(sourceIndex, QItemSelectionModel::Select);@

    or, simpler in one shot for updating the current and select just the current:
    @sourceSelectionModel->setCurrentIndex(sourceIndex, QItemSelectionModel::SelectCurrent);@it's like "once you've set the current may be you'd like to do it the selected one as well", this is the meaning "for convenience" in doc

    hope this helps :)

    Cheers!



  • I must admit that I find it very difficult to understand the definitions of http://qt-project.org/doc/qt-4.8/qitemselectionmodel.html#SelectionFlag-enum


  • Moderators

    [quote author="Moschops" date="1381239175"]I can't seem to get a clear answer to this question; is there a permanent, irrevocable link between what the user can see is "selected" in the tree view on the screen (i.e. the lines they highlight by clicking on them with CTRL-LEFT-CLICK) and what should be returned by @auto list = sourceSelectionModel->selectedIndexes();@

    At the moment, it seems that clicking things on the screen doesn't actually affect what is returned by @auto list = sourceSelectionModel->selectedIndexes();@
    [/quote]

    of course...you get the selected indexes (blue highlighted lines, depending on the system you are on and which style is set) by calling these methods. I think this method should be well understandable, they deliver the selected indexes in your table. If they are not, make sure you calling the methods on the correct instance of the selection model.

    The current index is as i said before the index with the dotted frame (when the widgets has input focus). There can only be one current index at the time. The current index can be moved by keyboard and is automatically set to the last index you selected by mouse. It has nothing todo with the selection in the table. Just even Qt mentions in the docs "current selection", just leave out the "selection" and it may clear things up for you. In the docs it means rather CURRENT-selection than "the current item selection" :)

    Hope this is clear now. If not tell me what exactly isn't for you.



  • The distinction between the current index and the selected indexes is clear; what I couldn't find was a clear statement that clicking something in the treeview on the screen was supposed to update the selection model's list of what was selected. I thought it was supposed to (and in my code currently it seems that it doesn't) but the documentation doesn't make it clear anywhere that I found that the two were automatically linked; I could imagine, for example, a system whereby clicking something on the screen did no more than send a "something has happened" signal, leaving it up to the coder to then catch that signal and interrogate the view and then manually update the selection. A massive pain, yes, but given that my code doesn't seem to update selection automatically at the moment, worth checking.

    Many thanks.



  • bq. I could imagine, for example, a system whereby clicking something on the screen did no more than send a “something has happened” signal, leaving it up to the coder to then catch that signal and interrogate the view and then manually update the selection

    QTreeView is already a specialization of QAbstractItemView with all stuffs you'd need ... if you want it from scratch you're free to reimplement it :)


  • Moderators

    there is no clear point in the docs. Actually it depends on the widget how the selection is changed. In most cases it is on a mouse click or even by keyboard.
    So to be sure you can checkout the mosue and key event handlers of the corresponding widget.

    Please post the code where you get the selection model and call selectedIndexes() on it. If your items widget has a visual selection you should receive it with selectedIndexes().



  • Thanks for all the help; I'm now digging into the models to see what's going on there. I'm sure that this code has more models than views, so some of them must be amalgamations or processed versions of others; I expect I've got an issue with the view's selected lines not going to the right model(s).


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.