如何在qml中动态地向模型添加数据?

时间:2018-12-03 15:11:42

标签: c++ qt qml

我正在构建一个音乐播放器应用程序,需要在其中基于专辑名称加载歌曲数据。 我已经通过将模型对象传递给main.cpp文件中的qml来初始化我的模型

      albumSongs globalSongListModel;
      ctxt->setContextProperty("globalSongListModel", &globalSongListModel);

在此类相册中的歌曲我具有以下属性

Q_PROPERTY(QString songName READ songName CONSTANT)
Q_PROPERTY(QString songFileUrl READ songFileUrl CONSTANT)
Q_PROPERTY(QString songDuration READ songDuration CONSTANT)

我在albumSongs类中有一个公共插槽,可从qml事件获取数据

public slots:
    QList<QObject*> getSongListByAlbumName(QString albumName){
        dbHelper dbh;
        QList<QObject*> songList;
        dbh.loadDataByAlbumName(albumName, songList);
        return songList;

    }

loadDataByAlbumName()函数在dbhelper类中声明如下

void dbHelper::loadDataByAlbumName(QString albumName, QList<QObject*>& songList) {
    QString query = "SELECT " + this->LI_DATA_TABLE_COLUMN_ONE + "," + this->LI_DATA_TABLE_COLUMN_TWO + "," + this->LI_DATA_TABLE_COLUMN_NINE +  " FROM " + this->LI_DATA_TABLE_NAME + " WHERE " + this->LI_DATA_TABLE_COLUMN_THREE + "=?";
    QSqlQuery sql;
    sql.prepare(query);
    sql.bindValue(0, albumName);
    sql.exec();
    while (sql.next()) {
        QString songName = sql.value(0).toString();
        QString songUrl = sql.value(1).toString();
        QString songDuration = sql.value(2).toString();
        songList.append(new albumSongs(songName, songUrl, songDuration));
    }
}

我可以成功地将数据从db加载到QListsongList 但是当我尝试在这样的qml文件中使用它

ListView {
    id: song_list_view
    width: 180; height: 200
    anchors.top: name.bottom;
    anchors.topMargin: 30
    delegate: Text {
        text: songName + " " + songFileUrl
    }




}

我在委托列中收到错误消息,指出未定义songName。

我一直在这样的鼠标进入事件上设置此模型

  onEntered: {
            song_list_view.model = globalSongListModel.getSongListByAlbumName(globalName)

        }

这是执行此任务的正确方法吗?我该怎么办才能解决错误?

1 个答案:

答案 0 :(得分:1)

首先,您的设计很糟糕:albumSongs如何具有songName,songFileUrl和songDuration吗?实际上,您必须具有一个用于存储Song数据的类和另一个具有返回列表的插槽的类管理器

问题所在,当模型为列表时,则必须使用modelData来访问每个项目,但是由于QML不知道该类,因此您仍然无法访问属性,因此必须向{注册{1}},以便您可以访问属性,但不能在QML中创建该类的对象:

qmlRegisterUncreatableType()

main.cpp

class Song : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QString songName READ songName CONSTANT)
    Q_PROPERTY(QString songFileUrl READ songFileUrl CONSTANT)
    Q_PROPERTY(QString songDuration READ songDuration CONSTANT)
public:
    explicit Song(const QString & songName="",
                  const QString & songFileUrl="",
                  const QString & songDuration="",
                  QObject *parent = nullptr):
        QObject(parent),
        m_songName(songName),
        m_songFileUrl(songFileUrl),
        m_songDuration(songDuration)
    {}
    QString songName() const{
        return m_songName;
    }

    QString songFileUrl() const{
        return  m_songFileUrl;
    }
    QString songDuration() const{
        return m_songDuration;
    }

private:
    QString m_songName;
    QString m_songFileUrl;
    QString m_songDuration;
};

class SongManager: public QObject{
    Q_OBJECT
public:
    explicit SongManager(QObject *parent=nullptr):
        QObject(parent)
    {}
public slots:
    static QList<QObject*> getSongListByAlbumName(const QString & name){
        QList<QObject*> songList;
        dbHelper dbh;
        dbh.loadDataByAlbumName(albumName, songList);
        return songList;
    }
};

*。qml

// ...
qmlRegisterUncreatableType<Song>("Songs", 1, 0, "Song", "Error class uncreatable");
// ...
SongManager manager;
ctxt->setContextProperty("manager", &manager);
// ...