Important: Please read the Qt Code of Conduct -

ListView with QSortFilterProxyModel displays empty lines resulting to the error "Unable to assign [undefined] to QString"

  • Hi,

    My app is using a ListView with its model coming from C++. Everything was ok using my custom QAbstractListModel following the doc.

    I now wish to add a filtering feature and thus, I've switched the model to be a QSortFilterProxyModel whose source is my QAbstractListModel.
    It is working but I've an issue I'd like to remove.

    Basically if my model doesn't fill the whole ListView, let's say only 7 rows where the view could display 10, then with a QSortFilterProxyModel, blank rows are displayed and selectable so I'm getting this error in the console: qrc:/Playlist.qml:54:17: Unable to assign [undefined] to QString
    Any idea what I should do to remove this behaviour?

    This is not happening when I'm using a QAbstractListModel. It's quite a bad user experience to be able to select blank rows. cf this snapshot
    alt text

    I've tried to do a Custom QSortFilterProxyModel as I'll need it anyway and try to trick the filter function to only accept valid rows but it doesn't seem to work. Here would be the code:

    bool PlayListProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
        ClementineRemote *remote = static_cast<PlayListModel *>(sourceModel())->remote();
        if (sourceRow < remote->nbSongs())
            return true;
            return false;

    I suppose sourceRow is the index on the model. remote->nbSongs() is returning the number of elements the model is exposing.

    Any idea what I could do?

    Edit1: if I display the ListView.count, I'm getting 14 using the QSortFilterProxyModel, 7 as expected with a QAbstractListModel. if it is the double exactly there must be a reason no?

    Edit2: no in fact it is random, if I use 8 elements in the model, I'm getting 11 rows in the view using the proxy (8 with the model)

  • wow really weird I found a way to make the BUG disappear by adding a debug which display the rowCount on the proxy model before I'm modifying the data (signalling the Model....)
    I didn't understand yesterday how I managed to fix the issue.
    Today by removing my debugs, the bug came back. By checking my commits, I managed to find up one debug line was needed to remove the bug...
    Here is my code to populate my data and Model:

    void ClementineRemote::rcvPlaylistSongs(pb::remote::ResponsePlaylistSongs *songs)
        // HACK to resolve ListView issue (displaying empty Rows after the number of elements)
        // cf
        qint32 proxyRows = _playlistProxyModel->rowCount();
    //    qDebug() << "proxy row count before removal: " << proxyRows;
        emit preClearSongs(_songs.size() - 1);
        emit postSongRemoved();
        emit preAddSongs(songs->songs_size() -1 );
        for (auto it = songs->songs().cbegin(), itEnd = songs->songs().cend();  it != itEnd; ++it)
        emit postSongAppended();

    So basically my model is connected on the _song list with those connections:

    void PlayListModel::setRemote(ClementineRemote *remote)
        if (_remote)
        _remote = remote;
        if (_remote) {
            connect(_remote, &ClementineRemote::preAddSongs, this, [=](int lastSongIdx) {
                beginInsertRows(QModelIndex(), 0, lastSongIdx);
            connect(_remote, &ClementineRemote::postSongAppended, this, [=]() {
            connect(_remote, &ClementineRemote::preClearSongs, this, [=](int lastSongIdx) {
                beginRemoveRows(QModelIndex(), 0, lastSongIdx);
            connect(_remote, &ClementineRemote::postSongRemoved, this, [=]() {

    So any idea what I'm doing wrong or why do I need to call this qint32 proxyRows = _playlistProxyModel->rowCount(); in order for the ListView to get the correct number of rows on the proxy once the Model is repopulated?
    Is it a bug?

  • The issue comes from the fact I'm updating the data from a ConnectionWorker Thread instead of the GUI one...
    I've opened another thread more general to see how I could fix that.

Log in to reply