Qt 小例子学习45 - QStringList视图播放列表
FileModel.h
#ifndef FILEMODEL_H
#define FILEMODEL_H
#include <QAbstractListModel>
#include <QDirIterator>
#include <QFuture>
#include <QMetaType>
#include <QUrl>
#include <QtConcurrent>
struct File
{
Q_GADGET
Q_PROPERTY(QString name MEMBER name)
Q_PROPERTY(QUrl url MEMBER url)
public:
QString name;
QUrl url;
File(const QString &name = "")
{
this->name = QFileInfo(name).fileName();
this->url = QUrl::fromLocalFile(name);
}
};
Q_DECLARE_METATYPE(File)
class FileModel : public QAbstractListModel
{
enum dashBoardRoles { NameRole = Qt::UserRole + 1, URLRole };
Q_OBJECT
Q_PROPERTY(QString folder READ folder WRITE setFolder NOTIFY folderChanged)
Q_PROPERTY(QStringList nameFilters READ nameFilters WRITE setNameFilters
NOTIFY nameFiltersChanged)
public:
FileModel(QObject *parent = Q_NULLPTR) : QAbstractListModel(parent) {}
Q_INVOKABLE QVariant get(int index)
{
return QVariant::fromValue(m_all_dirs[index]);
}
int rowCount(const QModelIndex &parent = QModelIndex()) const
{
Q_UNUSED(parent)
return m_all_dirs.count();
}
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const
{
if (index.row() < 0 && index.row() >= rowCount())
return QVariant();
File file = m_all_dirs[index.row()];
if (role == NameRole)
return file.name;
else if (role == URLRole)
return file.url;
return QVariant();
}
QHash<int, QByteArray> roleNames() const
{
QHash<int, QByteArray> roles;
roles[NameRole] = "fileName";
roles[URLRole] = "url";
return roles;
}
QString folder() const { return mFolder; }
void setFolder(const QString &folder)
{
if (mFolder == folder)
return;
mFolder = folder;
emit folderChanged();
findFiles();
}
QStringList nameFilters() const { return mNameFilters; }
void setNameFilters(const QStringList &nameFilters)
{
if (mNameFilters == nameFilters)
return;
mNameFilters = nameFilters;
emit nameFiltersChanged();
findFiles();
}
signals:
void folderChanged();
void nameFiltersChanged();
private:
void findFiles()
{
beginResetModel();
m_all_dirs.clear();
if (QDir(mFolder).exists())
{
QFuture<QStringList> future = QtConcurrent::run([ = ]()
{
QStringList files;
QDirIterator it(mFolder, mNameFilters, QDir::Files,
QDirIterator::Subdirectories);
while (it.hasNext())
{
files << it.next();
}
return files;
});
QStringList fullNames = future.result();
for (const QString &fullName : fullNames)
{
File file{fullName};
m_all_dirs << file;
}
}
endResetModel();
}
QString mFolder;
QList<File> m_all_dirs;
QStringList mNameFilters;
};
#endif // FILEMODEL_H
main.qml
import QtQuick 2.9
import QtQuick.Controls 2.2
import QtMultimedia 5.8
import com.eyllanesc.filemodel 1.0
ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("Tabs")
SwipeView {
id: swipeView
anchors.fill: parent
currentIndex: tabBar.currentIndex
Page {
ListView {
id: lv
width: 200; height: 400
Component {
id: fileDelegate
Text { text: fileName
MouseArea{
anchors.fill: parent
onClicked: playMusic(index)
}
}
}
model: FileModel{
id: myModel
folder: "/home/xz/视频"
nameFilters: ["*.mp4"]
}
delegate: fileDelegate
}
Button {
id: button
anchors.top: lv.bottom
width: parent.width
text: "Play"
background: Rectangle {
implicitHeight: 40
border.color: "#26282a"
border.width: 2
radius: 4
}
onClicked: playMusic(0)
}
}
Page {
MediaPlayer {
id: player
onStopped: {
if(status===MediaPlayer.EndOfMedia){
playMusic((lv.currentIndex+1) % lv.count)
}
}
}
VideoOutput {
id: video
anchors.fill: parent
source: player
}
}
}
function playMusic(index){
player.stop()
player.source = myModel.get(index).url
player.play()
swipeView.setCurrentIndex(1)
}
footer: TabBar {
id: tabBar
currentIndex: swipeView.currentIndex
TabButton {
text: qsTr("Page 1")
}
TabButton {
text: qsTr("Page 2")
}
}
}
main.cpp
#include "filemodel.h"
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QTimer>
#include <QDebug>
int main(int argc, char *argv[])
{
#if defined(Q_OS_WIN)
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif
QGuiApplication app(argc, argv);
qmlRegisterType<FileModel>("com.eyllanesc.filemodel", 1, 0, "FileModel");
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
return app.exec();
}