Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Passing a selectionModel.selection to C++



  • Hi.
    I have a TreeView showing data from a C++ proxy model. For this tree, I have a ItemSelectionModel of which I want to pass the current selection to the C++ backend:

    onClicked: {
        console.debug(selectionModel.selection)
        backend.removeSelected(selectionModel.selection)
    }
    

    The above console.debug prints out a valid QItemSelectionRange object:

    QItemSelectionRange(QPersistentModelIndex(2,0,0x559c021a3060,DataFilter(0x559c022256c0)),QPersistentModelIndex(2,0,0x559c021a3060,DataFilter(0x559c022256c0)))
    

    However, at the backend, where I simply do:

    void QmlInterface::removeSelected(QItemSelectionRange* range)
    {
        qLog(Debug) << range;
    }
    

    the value returned is 0x0.

    What am I missing here?



  • @Diracsbracket said in Passing a selectionModel.selection to C++:

    I think you are missing that this would not compile if written directly in C++, but QML does not "pick that up" (I don't use QML!).

    http://doc.qt.io/qt-5/qitemselectionmodel.html#selection :

    const QItemSelection QItemSelectionModel::selection() const

    That returns a QItemSelection (I don't see QItemSelectionRange there, but unless I'm barking up the wrong tree/looking at the wrong docs I leave that bit to you). You could pass that to

    void QmlInterface::removeSelected(const QItemSelectionRange& range)
    

    but given that you receive a pointer:

    void QmlInterface::removeSelected(QItemSelectionRange* range)
    

    does that not mean that your call needs to be

    backend.removeSelected(&selectionModel.selection)
    

    ? (You'll need to change your declaration to have const QItemSelectionRange* range.)



  • @JonB said in Passing a selectionModel.selection to C++:

    does that not mean that your call needs to be
    backend.removeSelected(&selectionModel.selection)

    NOPE! selectionModel.selection is a temporary object, you don't pass addresses of temporary objects around (plus JS doesn't really let you do it anyway). The rest of the answers is correct, you need to change void QmlInterface::removeSelected(QItemSelectionRange* range) to void QmlInterface::removeSelected(const QItemSelectionRange& range)



  • @VRonin
    Damn, sorry, I forgot about QML using JS, it looks sufficiently similar to C++ (just about!) that I thought that's what it was. Of course JS can't do pointers or references! But I'm happy that changing the C++ formal definition of the function will do the job :)

    P.S.
    Your sig's

    On a crusade to banish setItemWidget() from the holy land of Qt

    LOL :)



  • @VRonin

    selectionModel.selection is a temporary object, you don't pass addresses of temporary objects around
    change [...] to void QmlInterface::removeSelected(const QItemSelectionRange& range)

    Does this mean that (somehow) the compiled code will take a copy of the temporary object when passing/receiving it to that function definition? If so, how does it know to do that (some operator overload??) ?



  • @JonB, @VRonin ,
    You're right, it works with

    void removeSelected(const QItemSelection& range)
    

    I was blindly relying on the output of the debug console to get the type of the object returned, which shows a QItemSelectionRange, which I also found surprising. I should really learn to only rely on the source code...

    In any case, I have learned that qDebug() and console.debug() both show the type of QItemSelection as QItemSelectionRange and not as QItemSelection nor QList<QItemSelectionRange>.

    class Q_CORE_EXPORT QItemSelection : public QList<QItemSelectionRange>
     {...}
    

    Thanks to both of you,
    Cheers!



  • @JonB const references (const T&) are an exception, they extend the lifetime of the object. See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/1993/N0345.pdf



  • @VRonin
    Thanks for the reference. Unbelievable. Does somebody not think that some of these additions to C++ are just so complex that they might hinder development rather than help it? Anyway, I note the paper states:

    In Munich, we resolved that the temporary is bound to the life of the reference.

    If I am programming in England, then does this C++ rule still apply?



  • @JonB said in Passing a selectionModel.selection to C++:

    Does somebody not think that some of these additions to C++ are just so complex that they might hinder development rather than help it?

    This rule in particular is a perfect example of rule that a lot of people don't know and don't need to know about. it was a change so that people didn't need to overthink temporary variables.

    If I am programming in England, then does this C++ rule still apply?

    That paper is from 1993 and it's the initial proposal that was integrated in the standard, it is now a part of the rules all compilers follow


Log in to reply