Qt 小例子学习45 - QStringList视图播放列表

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();
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值