[Interest] QML ListView is not updated on model reset

Alexander Dyagilev alervdvcw at gmail.com
Mon Feb 27 18:59:28 CET 2017


Hello,

I've created a question on SO but nobody answered still...
(http://stackoverflow.com/questions/42468811/qml-listview-is-not-updated-on-model-reset)

Qt 5.8, Windows 10.

Quick Controls 2 application. In QML I have a ListView with a model 
derived from QAbstractListModel.

In the model I have the following code:

|voidMediaPlaylistModel::update(){beginResetModel();{std::unique_lock<std::mutex>lock(m_mutex);m_ids 
=m_playlist->itemsIds();}endResetModel();}|

Nothing happens in QML view after calling this method: list is not 
updated. If I go back and then forward (to the page with the ListView) - 
it'll contain updated data. Model object instance is the same always.

Am I doing something wrong?

*Update #2*:

C++ model code:

|MediaPlaylistModel::MediaPlaylistModel(QSharedPointer<AbstractMediaPlaylist>playlist,QObject*parent):base_t(parent),m_playlist(playlist){Q_ASSERT(m_playlist);connect(playlist.data(),&AbstractMediaPlaylist::changed,this,&MediaPlaylistModel::update);update();}QHash<int,QByteArray>MediaPlaylistModel::roleNames()const{QHash<int,QByteArray>result;result[IdRole]="id";result[TitleRole]="title";result[DurationRole]="duration";returnresult;}voidMediaPlaylistModel::update(){Q_ASSERT_SAME_THREAD;beginResetModel();{std::unique_lock<std::mutex>lock(m_mutex);m_ids 
=m_playlist->itemsIds();}endResetModel();}intMediaPlaylistModel::rowCount(constQModelIndex&parent)const{Q_UNUSED(parent);std::unique_lock<std::mutex>lock(m_mutex);returnstatic_cast<int>(m_ids.size());}QVariantMediaPlaylistModel::data(constQModelIndex&index,introle)const{autorow 
=static_cast<size_t>(index.row());intid 
=0;{std::unique_lock<std::mutex>lock(m_mutex);if(row 
 >=m_ids.size())returnQVariant();id =m_ids[row];}if(role 
==IdRole)returnid;QVariantresult;autoitem 
=m_playlist->item(id);switch(role){caseQt::DisplayRole:caseTitleRole:result 
=item.title;break;caseDurationRole:result 
=item.duration;break;}returnresult;}|

QML code:

|importQtQuick2.7importQtQuick.Controls2.0importcom.company.application 
1.0Page{id :root propertyintplaylistId propertyvar 
playlistApi:App.playlists.playlist(playlistId)ListView{id :playlist 
anchors.fill:parent model:playlistApi.model 
delegate:ItemDelegate{text:model.title width:parent.width 
onClicked:App.player.play(playlistId,model.id)}ScrollIndicator.vertical:ScrollIndicator{}}}|

*Update #3*:

When the model is updated (one item added), something strange happens 
with QML ListView: in addition to fact that it's not updated (and it 
does not call MediaPlaylistModel::data to retrieve new items), *existing 
items got damaged*. When I click on existed item, it's model.id property 
is always 0. E.g. at app start its model.id was 24, after one item added 
its model.id became 0.

*Update #4*:

App.playlists.playlist(playlistId) returns pointer to this class instance:

|classCppQmlPlaylistApi:publicQObject{Q_OBJECT Q_PROPERTY(QObject*model 
READ model NOTIFY modelChanged)Q_PROPERTY(QStringtitle READ title WRITE 
setTitle NOTIFY 
titleChanged)public:explicitCppQmlPlaylistApi(intplaylistId,QWeakPointer<CorePlaylistsManager>playlistsMgr,QObject*parent 
=0);QObject*model()const;QStringtitle()const;voidsetTitle(constQString&title);signals:voidmodelChanged();voidtitleChanged();voidloadPlaylistRequested(intid);protectedslots:voidonPlaylistLoaded(intid);voidonPlaylistRemoved(intid);protected:intm_playlistId 
=0;QWeakPointer<CorePlaylistsManager>m_playlistsMgr;QSharedPointer<QAbstractItemModel>m_model;};|

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20170227/435a1b5c/attachment.html>


More information about the Interest mailing list