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

效果预览:一、准备好对应的 QSqlTableModel#ifndefLOCALMUSICMODEL_H#defineLOCALMUSICMODEL_H#include<QObject>#include<QSqlTableModel>#include<QMediaPlayer>#include"libzplay.h"usingname…

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

效果预览:

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

一、准备好对应的 QSqlTableModel

#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

#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";
}

重点是

QHash<int, QByteArray> roleNames() const Q_DECL_OVERRIDE;

QVariant data(const QModelIndex &index, int role) const Q_DECL_OVERRIDE;

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

二、qml调用

main.cpp

qmlRegisterType<LocalMusicModel>("io.qt.CloudMusic", 1, 0, "LocalMusicModel");

qml:

import io.qt.CloudMusic 1.0

LocalMusicModel{
 
 id:localmusic;}
            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之从零开始编写网易云音乐目录

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

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

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(1)
blank

相关推荐

  • SPI中的极性CPOL和相位CPHA

    SPI中的极性CPOL和相位CPHA

  • 7个免费的服务器监控工具

    7个免费的服务器监控工具监控服务器是否正常与健康是非常重要的,确保用户始终可以访问你的服务。提高监控效率就需要使用高效的工具了,下面介绍10个免费的服务器监测工具。一、PerformanceCo-PilotPerformanceCo-Pilot(PCP)是一个开源框架和工具包,用于监控,分析和响应实时和历史系统性能的细节。PCP具有完全分布式,基于插件的架构,使其特别适用于复杂环境和系统的集中分析。可以使用C,C++,Perl和Python界面添加自定义性能指标。二、Antur…

  • win10强制删除文件夹(“你需要来自XXX的权限才能对此文件夹进行更改”的解决方法)

    win10强制删除文件夹(“你需要来自XXX的权限才能对此文件夹进行更改”的解决方法)win10强制删除文件夹(“你需要来自XXX的权限才能对此文件夹进行更改”的解决方法)使用命令行方式删除文件夹(这是目前可行的方式)第一步:以管理员账户打开powershell第二步:定位到要删除的文件夹所在目录第三步:给要删除的文件夹赋本机管理员Administrator权限第四步:修改对文件/文件夹的访问权限(赋删除权限)第五步:强制删除文件使用命令行方式删除文件夹(这是目前可行的方式)第一步:以管理员账户打开powershell快捷键win+x调出如下界面,点击WindowsPowerS

  • 操作系统维护相关总结「建议收藏」

    操作系统维护相关总结「建议收藏」操作系统维护相关总结声明:引用请注明出处http://blog.csdn.net/lg1259156776/说明:由于前段时间遭受了电脑固态硬盘故障系统崩溃,数据未及时备份无法读取而导致的痛苦,这里

  • LCD1602液晶使用介绍–(完整版)

    LCD1602液晶使用介绍–(完整版)lcd1602+c51介绍文章目录LCD1602介绍1602引脚信号说明控制器接口介绍1、基本操作时许2、状态字说明3、指令说明RAM地址映射控制时序图代码实现写入命令写数据试验例程CGRAM自定义字模(简易汉字显示)LCD1602介绍LCD1602液晶在实际的产品运用中也是比较多产品,应为前一段时间也正好用到了所以惊天就对LCD1602液晶做一个总结,方便以后阅读同时也希望能够帮住到需要的人,总结的可能存在错误欢迎指出!所谓的1602是指显示的时候,有2行内容每行有16个字符。其实这类字符型产

  • PL/SQL Developer连不上数据库解决方法

    PL/SQL Developer连不上数据库解决方法

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号