当前位置:网站首页>QML combines qsqltablemodel to dynamically load data MVC "recommended collection"
QML combines qsqltablemodel to dynamically load data MVC "recommended collection"
2022-07-25 20:01:00 【Full stack programmer webmaster】
Hello everyone , I meet you again , I'm your friend, Quan Jun .
Results the preview :
One 、 Prepare the corresponding 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);
/* You can see that this model is very powerful , And completely separated from SQL sentence , Even if you don't know much about databases ,
* You can also use it for most common operations . This model provides a buffer , You can save all changes to model in ,
* Only when we execute the commit modification , Will actually write to the database . Of course, it's also because we set its saving policy at the beginning :
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(" Unknown singer ");
break;
case Qt::UserRole+2:
if(sqlRecord.value(2).toString().isEmpty())
return tr(" Unknown album ");
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_);
}
// Get the information of all songs in the specified directory
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;
// If used directly LoadFileID3Ex function , There will be no long message
if(player->OpenFile((const char*) fileInfo.absoluteFilePath().toLocal8Bit(),sfAutodetect))
if(player->LoadID3Ex(&id3_info,1))
{
songInfo tempSongInfo;
tempSongInfo.title = QString::fromLocal8Bit(id3_info.Title); // Music title
tempSongInfo.Artist = QString::fromLocal8Bit(id3_info.Artist); // singer
tempSongInfo.path = fileInfo.absoluteFilePath(); // route
tempSongInfo.album = QString::fromLocal8Bit(id3_info.Album); // Album
// get stream info, Get duration information
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();// Submit database
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";
}The key is
QHash<int, QByteArray> roleNames() const Q_DECL_OVERRIDE;QVariant data(const QModelIndex &index, int role) const Q_DECL_OVERRIDE;Give you what you need data Set it up role, convenient qml To call .
Two 、qml call
main.cpp
qmlRegisterType<LocalMusicModel>("io.qt.CloudMusic", 1, 0, "LocalMusicModel");qml:
import io.qt.CloudMusic 1.0LocalMusicModel{
id:localmusic;} TableView{
id: tableview
anchors.fill: parent
visible: localmusic.m_musicNum >0
backgroundVisible: false;
frameVisible: false;
//itemDelegate: StandardTabelItemDelegate{} // agent
//headerDelegate: headerDele; // Header delegation
//rowDelegate: rowDele; // Bank entrustment
model: localmusic
TableViewColumn {
role: "title"
title: qsTr(" title ")
width: 300
}
TableViewColumn {
role: "singer"
title: qsTr(" singer ")
width: 300
}
TableViewColumn {
role: "album"
title: qsTr(" Album ")
width: 300
}
TableViewColumn {
role: "duration"
title: qsTr(" Duration ")
width: 300
}
}The agency will be further improved later
qml To write Netease cloud music catalog from scratch
Publisher : Full stack programmer stack length , Reprint please indicate the source :https://javaforall.cn/127739.html Link to the original text :https://javaforall.cn
边栏推荐
- Research and application of servo driver in robot
- Can you tell me whether mindspore supports torchvision Model directly uses the pre trained network, such as vgg16
- "Share" devaxpress asp Net v22.1 latest version system environment configuration requirements
- what is qml in qt
- Pytorch's transforms (numpy data type is converted to tensor, normalized and resized)
- 项目中new Promise和async、await中的使用,以及promise.all在项目中的实际应用
- 各厂商网络虚拟化的优势
- The use of new promise, async and await in the project, and the practical application of promise.all in the project
- C merge set
- On interface encryption
猜你喜欢

Creative drop-down multi choice JS plug-in download

How does tiktok break zero?

如何保证定制滑环质量

Six axis sensor use learning record

Connecting to the database warning establishing SSL connection without server's identity verification is not recommended

PMP每日一练 | 考试不迷路-7.25

Concept of IP address

Export and call of onnx file of pytorch model

给容器添加3d效果的副标题

C language learning diary 3 - realloc function
随机推荐
LP dual currency pledge liquidity mining DAPP system development logic analysis
IP地址的概念
Skiing mobile H5 game source code download
Illegal mix of collations for operation ‘UNION‘(bug记录)
919. Complete binary tree inserter
网络爬虫原理解析「建议收藏」
Recommended system topic | Minet: cross domain CTR prediction
Bash does not add single quotes to your string
导电滑环在机械设备方面的应用
Detailed evaluation of current popular redis visual management tools
CarSim仿真快速入门(十四)—CarSim-Simulink联合仿真
UNET and mask RCNN
Connecting to the database warning establishing SSL connection without server's identity verification is not recommended
Mindspore1.1.1 source code compilation and installation -- errors in the core compilation stage
From Tong Dai to "Tong Dai" and then to brand, the beauty of sudden profits has changed and remained unchanged
基于海思3559 高效率的 0延时 0拷贝 qt播放器方案
PyTorch 模型 onnx 文件的导出和调用
给容器添加3d效果的副标题
什么是聚类分析?聚类分析方法的类别[通俗易懂]
Common misunderstandings caused by a time reporting assistant of Blue Bridge Cup basic questions