Nominate our 2022 Qt Champions!

Force QAbstractItemModel to update role names or call roleNames() again

  • I'm currently implementing a model, which basically exposes a SQL-Table to QML. You can access the fields through the row number and the column name (role name). Deriving from QSqlTableModel does the main work (while this model works with columns not role names).

    However I have a little trouble exposing the column names to qml. I reimplemented the roleNames() method, but it seems that this method is only called once in the liftime of the model (clearing, reseting the model does not cause the model to re-read the role names).
    So if the table name or the selected columns changes, either role names are missing or columns cannot be referenced.

    How can I trigger the model to call roleNames() again?

  • Moderators

    In Qt4 there was a setter. For which the docs say that it has to be called before the model is used.
    In Qt5 the setter was removed.

    So it seems is not intended that the role names change during runtime.
    The only thing i can think of is to call reset() and let the view forget everything it knows from the model and force it to regather all the data.
    The disadvantage of reset() is that all states (selection, etc.) are lost.

    But i am wondering why the roleNames can change in your model?

  • @raven-worx
    They can change because, theoratically the user can change the statement property of the model from 'SELECT column1, column2 FROM table' to 'SELECT * FROM table' (with possibly more columns and therefore roles).

    But I guess then the declared view does not fit to the model anymore (if there was no column3 before, why should it now displayed by the view?). So it makes sense to prevent these fundamental changes you can make to a model. Its basically another model then.

    Thx for the answer anyway, seems I haven't thought it through enough :)

  • Moderators

    But the case you just described is a change of the column count and not a change of the rolenames?
    And column titles should be provided by headerData()

    Roles should normally be used to gather different information for a given index.
    And the roleNames() just exposes the roles as referenceable strings to QML.

    Related documentation.

  • @raven-worx
    Thats because no QML view knows of/uses columns of models (even the QML TableView uses roles not columns). The QML views are orthogonal to the C++ Views. No headerData() either.
    So what I do is mapping the column to a role, so I can access fields in a delegate at all, like this:

    delegate: Label {
        text: "Column 3: " + column3

    And for convenience, the columns should be referenced by the column name.

  • Moderators

    i see.
    Would have never expected such a "misdesign" IMHO in QML

    But have you tried the reset approach yet?

Log in to reply