前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >qml 结合 QSqlTableModel 动态加载数据 MVC「建议收藏」

qml 结合 QSqlTableModel 动态加载数据 MVC「建议收藏」

作者头像
全栈程序员站长
发布2022-07-25 19:31:33
9860
发布2022-07-25 19:31:33
举报
文章被收录于专栏:全栈程序员必看

大家好,又见面了,我是你们的朋友全栈君。

效果预览:

一、准备好对应的 QSqlTableModel

代码语言:javascript
复制
#ifndef LOCALMUSICMODEL_H
#define LOCALMUSICMODEL_H

#include <QObject>
#include <QSqlTableModel>
#include <QMediaPlayer>
#include "libzplay.h"
using namespace libZPlay;

struct songInfo
{
    QString Artist;
    QString title;
    QString album;
    qint32 duration = 0;
    QString path;

};

class LocalMusicModel : public QSqlTableModel
{
    Q_OBJECT
    Q_PROPERTY(int m_musicNum READ musicNum WRITE setMusicNum NOTIFY musicNumChanged)



public:
    explicit LocalMusicModel(QObject *parent = nullptr);
    QVariant data(const QModelIndex &index, int role) const Q_DECL_OVERRIDE;
    QHash<int, QByteArray> roleNames() const Q_DECL_OVERRIDE;

    Q_INVOKABLE void reloadMusicRecord(const QString &path);
    int musicNum(){return m_musicNum;}
    void setMusicNum(int val){
        m_musicNum = val;
        emit musicNumChanged();
    }

signals:
    void musicNumChanged();

private:
    void parseMusicInfo(QString path);
    void clearDb();

private:
    ZPlay *player;
    int m_musicNum = 0;

};

#endif // LOCALMUSICMODEL_H
代码语言:javascript
复制
#include "localmusicmodel.h"

#include <QDateTime>
#include <QSqlRecord>
#include <QDebug>
#include <QSqlError>
#include <QSqlQuery>
#include <QDir>


static const char *localMusicTableName = "LocalMusicInfo";

static void createTable()
{
    if (QSqlDatabase::database().tables().contains(localMusicTableName)) {
        // The table already exists; we don't need to do anything.
        return;
    }

    QSqlQuery query;
    QString sql_ = QStringLiteral("CREATE TABLE IF NOT EXISTS [LocalMusicInfo] (         \
                                  [title] VARCHAR2 , \
                                  [singer] VARCHAR2 , \
                                  [album] VARCHAR2 , \
                                  [duration] INTEGER ,\
                                  [path] VARCHAR2 NOT NULL ,          \
                                  UNIQUE([path]) ON CONFLICT REPLACE \
                                  )");


    if (!query.exec(sql_)) {
        qFatal("Failed to query database: %s", qPrintable(query.lastError().text()));
    }

    //query.exec("INSERT INTO LocalMusicInfo VALUES('title', 'singer', 'album', 123,'c://')");
}


LocalMusicModel::LocalMusicModel(QObject *parent)
    : QSqlTableModel(parent)
{
    createTable();
    setTable(localMusicTableName);
    /*可以看到这个模型很强大,而且完全脱离了SQL语句,就算你不怎么懂数据库,
     * 也可以利用它进行大部分常用的操作。这个模型提供了缓冲区,可以将所有修改先保存到model中,
     * 只有当我们执行提交修改后,才会真正写入数据库。当然这也是因为我们在最开始设置了它的保存策略:
    submitAll();   revertAll();*/
    setEditStrategy(QSqlTableModel::OnManualSubmit);
    select();
    player = CreateZPlay();

    setMusicNum(this->rowCount());
}

QVariant LocalMusicModel::data(const QModelIndex &index, int role) const
{
    if (role < Qt::UserRole)
            return QSqlTableModel::data(index, role);

    const QSqlRecord sqlRecord = record(index.row());

    //qDebug() << sqlRecord.value(role - Qt::UserRole);

    switch (role) {
    case Qt::UserRole:
        if(sqlRecord.value(0).toString().isEmpty())
        {
            QString path = sqlRecord.value(role - Qt::UserRole + 4).toString();
            path =  path.right(path.lastIndexOf('/'));
            path.chop(4);
            return  path.simplified();
        }
        break;
    case Qt::UserRole+1:
        if(sqlRecord.value(1).toString().isEmpty())
            return tr("未知歌手");
        break;
    case Qt::UserRole+2:
        if(sqlRecord.value(2).toString().isEmpty())
            return tr("未知专辑");
        break;
    case Qt::UserRole+3:
        int time = sqlRecord.value(3).toInt();
        return QString("%1:%2").arg(time/60).arg(time%60,2,10,QChar('0'));
    }
    return sqlRecord.value(role - Qt::UserRole);
}

QHash<int, QByteArray> LocalMusicModel::roleNames() const
{
    QHash<int, QByteArray> names;
    names[Qt::UserRole] = "title";
    names[Qt::UserRole + 1] = "singer";
    names[Qt::UserRole + 2] = "album";
    names[Qt::UserRole + 3] = "duration";
    names[Qt::UserRole + 4] = "path";
    return names;
}

void LocalMusicModel::reloadMusicRecord(const QString &path_)
{
    parseMusicInfo(path_);
}

//获取指定目录下所有歌曲信息
void LocalMusicModel::parseMusicInfo(QString path)
{
    QList<songInfo> songRecords;
    QStringList dirList=path.split(",");
    QString temp;
    foreach (temp, dirList) {
        temp=temp.right(temp.length()-8);
        QDir dir(temp);
        dir.setNameFilters(QStringList() << "*.mp3" << "*.flac" << "*.wav");
        QFileInfoList fileList=dir.entryInfoList();
        QFileInfo fileInfo;

        foreach (fileInfo, fileList) {
            TID3InfoEx id3_info;
            //如果直接使用LoadFileID3Ex函数,会得不到时长信息
            if(player->OpenFile((const char*) fileInfo.absoluteFilePath().toLocal8Bit(),sfAutodetect))
                if(player->LoadID3Ex(&id3_info,1))
                {
                    songInfo tempSongInfo;
                    tempSongInfo.title = QString::fromLocal8Bit(id3_info.Title);    //音乐标题
                    tempSongInfo.Artist = QString::fromLocal8Bit(id3_info.Artist);  //歌手
                    tempSongInfo.path = fileInfo.absoluteFilePath();                //路径
                    tempSongInfo.album = QString::fromLocal8Bit(id3_info.Album);    //专辑
                    // get stream info,获取时长信息
                    TStreamInfo pInfo;
                    player->GetStreamInfo(&pInfo);
                    tempSongInfo.duration =pInfo.Length.sec;
                    songRecords.append(tempSongInfo);
                }
                else
                {
                    qDebug() << QString("No ID3 data:%1\r\n\r\n").arg(QString::fromLocal8Bit(player->GetError()));
                }
            else
            {
                qDebug() << "LoadID3Ex faild";
            }
        }
    }

    clearDb();

    QSqlRecord newRecord = record();
    for(auto songItem : songRecords)
    {
        newRecord.setValue("title", songItem.title);
        newRecord.setValue("singer", songItem.Artist);
        newRecord.setValue("album", songItem.album);
        newRecord.setValue("duration", songItem.duration);
        newRecord.setValue("path", songItem.path);

        if (!insertRecord(rowCount(), newRecord)) {
            qWarning() << "Failed to send message:" << lastError().text();
            return;
        }
    }

    submitAll();//提交数据库
    setMusicNum(songRecords.size());
}

void LocalMusicModel::clearDb()
{
    if (!QSqlDatabase::database().tables().contains(localMusicTableName)) {
        createTable();
    }

    QSqlQuery query;
    QString sql_ = QStringLiteral("delete from [LocalMusicInfo]");

    if (!query.exec(sql_)) {
        qFatal("Failed to query database: %s", qPrintable(query.lastError().text()));
    }
    qDebug() << "clear table ok";
}

重点是

代码语言:javascript
复制
QHash<int, QByteArray> roleNames() const Q_DECL_OVERRIDE;
代码语言:javascript
复制
QVariant data(const QModelIndex &index, int role) const Q_DECL_OVERRIDE;

给你需要的数据设置好role,方便qml进行调用。

二、qml调用

main.cpp

代码语言:javascript
复制
qmlRegisterType<LocalMusicModel>("io.qt.CloudMusic", 1, 0, "LocalMusicModel");

qml:

代码语言:javascript
复制
import io.qt.CloudMusic 1.0
代码语言:javascript
复制
LocalMusicModel{
 
 id:localmusic;}
代码语言:javascript
复制
            TableView{
                id: tableview
                anchors.fill: parent
                visible: localmusic.m_musicNum >0
                backgroundVisible: false;
                frameVisible: false;
                //itemDelegate: StandardTabelItemDelegate{} //代理
                //headerDelegate: headerDele;  //表头委托
                //rowDelegate: rowDele;   //行委托
                model: localmusic

                TableViewColumn {
                          role: "title"
                          title: qsTr("标题")
                          width: 300
                      }
                TableViewColumn {
                          role: "singer"
                          title: qsTr("歌手")
                          width: 300
                      }
                TableViewColumn {
                          role: "album"
                          title: qsTr("专辑")
                          width: 300
                      }
                TableViewColumn {
                          role: "duration"
                          title: qsTr("时长")
                          width: 300
                      }
            }

代理待后面继续完善

qml之从零开始编写网易云音乐目录

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/127739.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022年4月1,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、准备好对应的 QSqlTableModel
  • 二、qml调用
  • 代理待后面继续完善
  • qml之从零开始编写网易云音乐目录
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档