Qt QML ListView在模型重置时未更新

Qt QML ListView在模型重置时未更新,qt,qtquickcontrols2,Qt,Qtquickcontrols2,Qt5.8,Windows10 快速控制2应用程序。在QML中,我有一个ListView,其模型是从QabStretchListModel派生的 在模型中,我有以下代码: void MediaPlaylistModel::update() { beginResetModel(); { std::unique_lock<std::mutex> lock(m_mutex); m_ids = m_playlist->itemsIds()

Qt5.8,Windows10

快速控制2应用程序。在QML中,我有一个ListView,其模型是从QabStretchListModel派生的

在模型中,我有以下代码:

void MediaPlaylistModel::update()
{
    beginResetModel();
    {
        std::unique_lock<std::mutex> lock(m_mutex);
        m_ids = m_playlist->itemsIds();
    }
    endResetModel();
}
更新#3

当模型被更新(添加了一项)时,QML ListView会发生一些奇怪的事情:除了它没有被更新(并且它没有调用 MediaPlayModel::用于检索新项目的数据),现有项目已损坏。单击现有项时,其model.id属性始终为0。例如,在应用程序启动时,其model.id为24,添加一个项目后,其model.id变为0

更新#4

App.playlists.playlist(playlistId)返回指向该类实例的指针:

class CppQmlPlaylistApi :
        public QObject
{
    Q_OBJECT
    Q_PROPERTY(QObject* model READ model NOTIFY modelChanged)
    Q_PROPERTY(QString title READ title WRITE setTitle NOTIFY titleChanged)

public:
    explicit CppQmlPlaylistApi(
            int playlistId,
            QWeakPointer<CorePlaylistsManager> playlistsMgr,
            QObject *parent = 0);

    QObject* model() const;

    QString title() const;
    void setTitle(const QString &title);

signals:
    void modelChanged();
    void titleChanged();
    void loadPlaylistRequested(int id);

protected slots:
    void onPlaylistLoaded(int id);
    void onPlaylistRemoved(int id);

protected:
    int m_playlistId = 0;
    QWeakPointer<CorePlaylistsManager> m_playlistsMgr;
    QSharedPointer<QAbstractItemModel> m_model;
};
CppQmlPlaylistApi类:
公共质量对象
{
Q_对象
Q_属性(QObject*模型读取模型通知模型更改)
Q_属性(QString title READ title WRITE setTitle NOTIFY title changed)
公众:
显式CppQmlPlaylistApi(
int播放ID,
QWeakPointer播放列表SMGR,
QObject*parent=0);
QObject*model()常量;
QString title()常量;
无效设置标题(常量字符串和标题);
信号:
void modelChanged();
无效标题已更改();
无效加载请求(int-id);
受保护插槽:
void onplayload(int-id);
已删除无效数据(int-id);
受保护的:
int m_playlaid=0;
QWeakPointer m_playlistmgr;
QSharedPointer模型;
};

您提供的代码很好。在QML方面,只要您的模型是绑定的,而不是在JS中动态地重新创建的,您也应该很好

ListView {
    model: mediaPlaylistModel
}
如果意外地过载了
beginResetModel
endResetModel
,则可能会出现问题。出于测试目的,您可以尝试发出
qabstractemmodel::modelReset()
信号,看看它是否改变了什么


使用QabstracteModel很容易错过一些东西,导致无法继续工作

提供的代码很好。在QML方面,只要您的模型是绑定的,而不是在JS中动态地重新创建的,您也应该很好

ListView {
    model: mediaPlaylistModel
}
如果意外地过载了
beginResetModel
endResetModel
,则可能会出现问题。出于测试目的,您可以尝试发出
qabstractemmodel::modelReset()
信号,看看它是否改变了什么


使用QabstracteModel很容易错过一些东西,导致无法继续工作

模型在非GUI线程中。 我收到了这些调试消息(感谢AlexanderVX指出我的问题):


将模型对象移动到GUI线程修复了该问题。

模型处于非GUI线程中。 我收到了这些调试消息(感谢AlexanderVX指出我的问题):


将模型对象移动到GUI线程修复了问题。

不,我不重写这些方法。不,我不覆盖这些方法。没有提供QML代码,也没有用于更新模型的C++代码。添加了它。(更新#2)。确保
auto row=static_cast(index.row())是正确的。
App.playlists.playlist(playlist id)
返回什么?它是正确的。App.playlists.playlist返回指向QObject的指针。请看更新第4页。我看了第4页,没有从C++类中暴露出来的属性播放列表。BTW是否有调试消息?没有提供QML代码,没有用于更新模型的C++代码。添加了它。(更新#2)。确保
auto row=static_cast(index.row())是正确的。
App.playlists.playlist(playlist id)
返回什么?它是正确的。App.playlists.playlist返回指向QObject的指针。请看更新第4页。我看了第4页,没有从C++类中暴露出来的属性播放列表。顺便问一下,有调试消息吗?
class CppQmlPlaylistApi :
        public QObject
{
    Q_OBJECT
    Q_PROPERTY(QObject* model READ model NOTIFY modelChanged)
    Q_PROPERTY(QString title READ title WRITE setTitle NOTIFY titleChanged)

public:
    explicit CppQmlPlaylistApi(
            int playlistId,
            QWeakPointer<CorePlaylistsManager> playlistsMgr,
            QObject *parent = 0);

    QObject* model() const;

    QString title() const;
    void setTitle(const QString &title);

signals:
    void modelChanged();
    void titleChanged();
    void loadPlaylistRequested(int id);

protected slots:
    void onPlaylistLoaded(int id);
    void onPlaylistRemoved(int id);

protected:
    int m_playlistId = 0;
    QWeakPointer<CorePlaylistsManager> m_playlistsMgr;
    QSharedPointer<QAbstractItemModel> m_model;
};
ListView {
    model: mediaPlaylistModel
}
QObject::connect: Cannot queue arguments of type 'QQmlChangeSet' 
(Make sure 'QQmlChangeSet' is registered using qRegisterMetaType().)