QML GridView - report current selection to C++ code



  • I have a C++ QAbstracListModel subclass that I have set to a QML GridView.

    What I want is to know the current selection of the GridView in C++, so that I could synchronize the selection from it with another C++-based view. Usually, if both views are C++-based, then the solution is to use a common QItemSelectionModel. Since I want to use this standard approach, I am currently trying to employ it to my hybrid views' case.

    What I have currently done is to create a QItemSelectionModel, make it use my QAbstractListModel subclass and expose both to QML:
    @
    DataModel* const dataModel = new DataModel( this );
    QItemSelectionModel* const dataSelectionModel = new QItemSelectionModel( dataModel );
    QDeclarativeView* view = new QDeclarativeView;
    view->rootContext()->setContextProperty( "dataModel", dataModel );
    view->rootContext()->setContextProperty( "dataSelectionModel", dataSelectionModel );
    @

    What I have done in the QML's GridView:
    @
    GridView {
    id: gridView
    model: dataModel

    onCurrentIndexChanged: {
        dataSelectionModel.setCurrentIndex( gridView.model.modelIndex( currentIndex ), 0x0002 | 0x0010 )
    }
    

    }
    @

    The numbers: 0x0002 | 0x0010, are:
    @
    QItemSelectionModel::Select 0x0002 // All specified indexes will be selected.
    QItemSelectionModel::Current 0x0010 // The current selection will be updated.
    QItemSelectionModel::SelectCurrent Select | Current
    @

    I exposed these to QML as well, but for the current test case I have given them as numbers.

    What I want to achieve is to set the currently selected QModelIndex from the QML's GridView to the common QItemSelectionModel.
    Currently, I receive an error for:
    GridView.qml: TypeError: Result of expression 'gridView.model.modelIndex' [undefined] is not a function.

    Any suggestions how to achieve this?



  • [quote author="napajejenunedk0" date="1364800580"]
    What I want to achieve is to set the currently selected QModelIndex from the QML's GridView to the common QItemSelectionModel.
    Currently, I receive an error for:
    GridView.qml: TypeError: Result of expression 'gridView.model.modelIndex' [undefined] is not a function.

    Any suggestions how to achieve this?
    [/quote]

    Could you please share the source code of DataModel? I guess it inherits QAbstractItemModel but it seems that you have not declared a method with name modelIndex.



  • bq. I have a C++ QAbstractListModel subclass ...

    The model is a derived QAbstractListModel. Yes there is no modelIndex method, but what is strange is that Googling about the way to get the QModelIndex, I found several places where function having this name was used.

    I presume I should override the index() function in my derived class and mark it as invokable by QML, since the QAbstractListModel doesn't provide it as such:
    @
    Q_INVOKABLE virtual QModelIndex index ( int row, int column = 0, const QModelIndex & parent = QModelIndex() ) const;
    @

    or:
    @
    public slots:
    virtual QModelIndex index ( int row, int column = 0, const QModelIndex & parent = QModelIndex() ) const;
    @

    since slots are automatically marked as invokable by QML. The second is meaningless, I think.
    I have currently made another solution: I am using a helper class, that I have registered using qmlRegisterType ... and then I inform an instance of a QItemSelection model of the current selection.

    This is not a good solution, since if the GridView allows for sorting or reordering the data, I will get the wrong indices. So, probably the best question is if it is possible to set a QItemSelectionModel to a QML GridView?



  • [quote author="napajejenunedk0" date="1364823576"]bq. I have a C++ QAbstractListModel subclass ...

    The model is a derived QAbstractListModel. Yes there is no modelIndex method, but what is strange is that Googling about the way to get the QModelIndex, I found several places where function having this name was used.
    [/quote]

    OK, in this case the error is not surprising because your are calling a non-existing method. It is always better to rely on the "official Qt documentation of QAbstractListModel":http://qt-project.org/doc/qt-5.0/qtcore/qabstractlistmodel-members.html rather than just on examples.

    I don't have much experience with QML and I don't fully understand your case. But in my opinion your approach seems a bit complicated and may be you should try to simplify it. Since you can get the current "index and item":http://qt-project.org/doc/qt-5.0/qtquick/qml-qtquick2-gridview.html#currentIndex-prop of the GridView hence you should be able to process it at a C++ and do what ever you what with the data and to update a QWidget. Btw "this thread":http://qt-project.org/forums/viewthread/20090 might give you some ideas for handling updates at the data of a GridView.



  • What I've found is that currently the easiest way to know whenever the
    GridView's currently selected index has changed is to create a helper class
    that has a Qt metasystem registered property:

    @
    Q_PROPERTY( int selectedIndex READ selectedIndex WRITE setSelectedIndex
    NOTIFY selectedIndexChanged )
    @

    Then make your helper class accessible by QML:
    @
    qmlRegisterType< ItemSelectionModelQmlHelper >( "Models.Tools", 1, 0,
    "ItemSelectionModelQmlHelper" );
    @

    Then create an instantiate of this class and expose it to QML:
    @
    QDeclarativeView* const view = new QDeclarativeView;
    ItemSelectionModelQmlHelper* const helper = new ItemSelectionModelQmlHelper(
    this );
    view->rootContex()->setContextProperty( "_itemSelectionModelQmlHelper",
    helper );
    @

    Then one can create the QItemSelectionModel and listen to the helper's
    signal, so that to set the current index of the QItemSelectionModel.

    Of course as mentioned above, if you use a sorting or filtration of the data
    being displayed in the GridView the currently selected GridView item's index
    may not correspond to a row in your QAbstractItemModel derived class.
    This won't be the case if you have done the filtration and/or sorting in C++
    using the QSortFilterProxyModel. The problem with the non-coresponding index
    will arise only if you do the sorting/filtration in QML.

    It would be best if GridView has the option to specify a selection model.


Log in to reply
 

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