QT 播放器之列表[通俗易懂]

QT 播放器之列表[通俗易懂]列表只需要显示字符串就行。直接选择使用QListView既然用到了View肯定是需要Model。该Model需要存储当前播放索引 添加的媒体链接 播放模式第一步,重写QAbstractItemModel的虚函数//QAbstractItemModelinterfacepublic:QVariantdata(constQModelIndex&a…

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

列表只需要显示字符串就行。直接选择使用 QListView

既然用到了View肯定是需要Model。该Model需要存储

  • 当前播放索引
  • 添加的媒体链接
  • 播放模式

第一步,重写 QAbstractItemModel 的虚函数

    // QAbstractItemModel interface
public:
    QVariant data(const QModelIndex &index, int role) const;
    int rowCount(const QModelIndex &parent=QModelIndex()) const;
    int columnCount(const QModelIndex &parent=QModelIndex()) const;

    QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const;
    QModelIndex parent(const QModelIndex &child=QModelIndex()) const;
    bool setData(const QModelIndex &index, const QVariant &value, int role);
    bool removeRows(int row, int count, const QModelIndex &parent=QModelIndex());

private:
    QList<QMediaContent> m_data;
QVariant MediaListModel::data(const QModelIndex &index, int role) const
{
    if(index.isValid() && role == Qt::DisplayRole)
    {
        if(index.row()>=0 && index.row()<m_data.size() && index.column()==0)
        {
            return  QFileInfo(m_data.at(index.row()).canonicalUrl().path()).fileName();
        }
    }
    return QVariant();
}

int MediaListModel::rowCount(const QModelIndex &parent) const
{
    Q_UNUSED(parent);
    return m_data.size();
}


int MediaListModel::columnCount(const QModelIndex &parent) const
{
    Q_UNUSED(parent);
    return 1;
}

bool MediaListModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
    Q_UNUSED(role);
    if(index.isValid() && value.isValid() && index.row()>=0 &&index.row()<m_data.size() && index.column()==0){
        m_data.replace(index.row(),value.toUrl());
        emit dataChanged(index,index);
        return true;
    }
    return false;
}

QModelIndex MediaListModel::index(int row, int column, const QModelIndex &parent) const
{
    return row>=0 &&
            row<m_data.size() &&
            column==0 &&
            !parent.isValid()
            ?createIndex(row,column)
           :QModelIndex();
}

QModelIndex MediaListModel::parent(const QModelIndex &child) const
{
    Q_UNUSED(child);
    return QModelIndex();
}

bool MediaListModel::removeRows(int row, int count, const QModelIndex &parent)
{
    Q_UNUSED(parent);
    if(row+count<=m_data.size() && row>=0 &&count>=0)
    {
        for(int i=0;i<count;i++)
        {
            m_data.removeAt(row);
        }
        return true;
    }
    return false;
}

添加数据以及查询数据

    void insert(const QUrl &url);
    QMediaContent media(const QModelIndex &index)const;

void MediaListModel::insert(const QUrl &url)
{
    if(url.isValid()){
        m_data.append(url);
        QModelIndex index=createIndex(m_data.size()-1,0);
        emit dataChanged(index,index);
    }
}

QMediaContent MediaListModel::media(const QModelIndex &index) const
{
    if(index.isValid() && index.row()>=0&&index.row()<m_data.size())
    {
        return m_data[index.row()];
    }
    return QMediaContent();
}

之后设置播放索引以及查询索引

    QModelIndex currentIndex()const;
    void setPlayIndex(int index);

QModelIndex MediaListModel::currentIndex() const
{
    return createIndex(m_index,0);
}

void MediaListModel::setPlayIndex(int index)
{
    m_index=index;
}

设置播放模式和查询播放模式

enum PlaybackMode { CurrentItemOnce, CurrentItemInLoop, Sequential, Loop, Random };


void setPlaybackMode(PlaybackMode mode);
PlaybackMode playbackMode()const;


void MediaListModel::setPlaybackMode(MediaListModel::PlaybackMode mode)
{
    if(m_mode!=mode)
    {
        m_mode=mode;
    }
}

MediaListModel::PlaybackMode MediaListModel::playbackMode() const
{
    return m_mode;
}

 

完整代码:

#ifndef MEDIALISTMODEL_H
#define MEDIALISTMODEL_H

#include <QAbstractItemModel>
#include <QMediaContent>

class MediaListModel : public QAbstractItemModel
{
    Q_OBJECT
public:

    enum PlaybackMode { CurrentItemOnce, CurrentItemInLoop, Sequential, Loop, Random };

    explicit MediaListModel(QObject *parent = nullptr);
    void insert(const QUrl &url);
    QMediaContent media(const QModelIndex &index)const;
    void setPlaybackMode(PlaybackMode mode);
    PlaybackMode playbackMode()const;
    QModelIndex currentIndex()const;
    void setPlayIndex(int index);

    // QAbstractItemModel interface
public:
    QVariant data(const QModelIndex &index, int role) const;
    int rowCount(const QModelIndex &parent=QModelIndex()) const;
    int columnCount(const QModelIndex &parent=QModelIndex()) const;

    QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const;
    QModelIndex parent(const QModelIndex &child=QModelIndex()) const;
    bool setData(const QModelIndex &index, const QVariant &value, int role);
    bool removeRows(int row, int count, const QModelIndex &parent=QModelIndex());


private:
    int m_index;
    PlaybackMode m_mode=CurrentItemOnce;
    QList<QMediaContent> m_data;

};

#endif // MEDIALISTMODEL_H
#include "medialistmodel.h"

#include <QFileInfo>
#include <QDebug>

MediaListModel::MediaListModel(QObject *parent) : QAbstractItemModel(parent)
{
    m_index=-1;
}

void MediaListModel::insert(const QUrl &url)
{
    if(url.isValid()){
        m_data.append(url);
        QModelIndex index=createIndex(m_data.size()-1,0);
        emit dataChanged(index,index);
    }
}

QMediaContent MediaListModel::media(const QModelIndex &index) const
{
    if(index.isValid() && index.row()>=0&&index.row()<m_data.size())
    {
        return m_data[index.row()];
    }
    return QMediaContent();
}

void MediaListModel::setPlaybackMode(MediaListModel::PlaybackMode mode)
{
    if(m_mode!=mode)
    {
        m_mode=mode;
    }
}

MediaListModel::PlaybackMode MediaListModel::playbackMode() const
{
    return m_mode;
}

QModelIndex MediaListModel::currentIndex() const
{
    return createIndex(m_index,0);
}

void MediaListModel::setPlayIndex(int index)
{
    m_index=index;
}

QVariant MediaListModel::data(const QModelIndex &index, int role) const
{
    if(index.isValid() && role == Qt::DisplayRole)
    {
        if(index.row()>=0 && index.row()<m_data.size() && index.column()==0)
        {
            return  QFileInfo(m_data.at(index.row()).canonicalUrl().path()).fileName();
        }
    }
    return QVariant();
}

int MediaListModel::rowCount(const QModelIndex &parent) const
{
    Q_UNUSED(parent);
    return m_data.size();
}


int MediaListModel::columnCount(const QModelIndex &parent) const
{
    Q_UNUSED(parent);
    return 1;
}

bool MediaListModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
    Q_UNUSED(role);
    if(index.isValid() && value.isValid() && index.row()>=0 &&index.row()<m_data.size() && index.column()==0){
        m_data.replace(index.row(),value.toUrl());
        emit dataChanged(index,index);
        return true;
    }
    return false;
}

QModelIndex MediaListModel::index(int row, int column, const QModelIndex &parent) const
{
    return row>=0 &&
            row<m_data.size() &&
            column==0 &&
            !parent.isValid()
            ?createIndex(row,column)
           :QModelIndex();
}

QModelIndex MediaListModel::parent(const QModelIndex &child) const
{
    Q_UNUSED(child);
    return QModelIndex();
}

bool MediaListModel::removeRows(int row, int count, const QModelIndex &parent)
{
    Q_UNUSED(parent);
    if(row+count<=m_data.size() && row>=0 &&count>=0)
    {
        for(int i=0;i<count;i++)
        {
            m_data.removeAt(row);
        }
        return true;
    }
    return false;
}


 

列表需要以下功能

  • 双击播放视频
  • 右键播放视频
  • 添加文件
  • 添加文件夹
  • 载入播放列表
  • 保存播放列表
  • 删除选中项
  • 清空播放列表
  • 清空无效文件
  • 设置播放模式
  • 打开文件目录

 

设置一下菜单,播放模式菜单为互斥的~

    QMenu *m_menu;
    QString m_playModeKey[5];
    MediaListModel::PlaybackMode m_playModeValue[5];
    QAction *m_play;
    QAction *m_deleteSelect;
    QAction *m_openFolder;


    setEditTriggers(QAbstractItemView::NoEditTriggers);
    setSelectionMode(QAbstractItemView::ExtendedSelection);
    setContextMenuPolicy(Qt::CustomContextMenu);

    m_playModeKey[0] = QStringLiteral("顺序播放");
    m_playModeKey[1] = QStringLiteral("单个播放");
    m_playModeKey[2] = QStringLiteral("随机播放");
    m_playModeKey[3] = QStringLiteral("单个循环");
    m_playModeKey[4] = QStringLiteral("列表循环");

    m_playModeValue[0]=MediaListModel::Sequential;
    m_playModeValue[1]=MediaListModel::CurrentItemOnce;
    m_playModeValue[2]=MediaListModel::Random;
    m_playModeValue[3]=MediaListModel::CurrentItemInLoop;
    m_playModeValue[4]=MediaListModel::Loop;

    m_menu = new QMenu();
    m_play = m_menu->addAction(QStringLiteral("播放"));
    auto addFile = m_menu->addAction(QStringLiteral("添加文件"));
    auto addFolder = m_menu->addAction(QStringLiteral("添加文件夹"));
    auto load = m_menu->addAction(QStringLiteral("载入播放列表"));
    auto save = m_menu->addAction(QStringLiteral("保存播放列表"));
    m_deleteSelect = m_menu->addAction(QStringLiteral("删除选中项"));
    auto clearPlayList = m_menu->addAction(QStringLiteral("清空播放列表"));
    auto clearInvalidfiles = m_menu->addAction(QStringLiteral("清空无效文件"));
    auto loopMode = m_menu->addMenu(QStringLiteral("循环模式"));
    m_openFolder = m_menu->addAction(QStringLiteral("打开文件目录"));

    QAction* loopActions[5];
    loopActions[0] = loopMode->addAction(m_playModeKey[0]);
    loopActions[1] =loopMode->addAction(m_playModeKey[1]);
    loopActions[2] =loopMode->addAction(m_playModeKey[2]);
    loopActions[3] =loopMode->addAction(m_playModeKey[3]);
    loopActions[4] =loopMode->addAction(m_playModeKey[4]);

    QActionGroup *group = new QActionGroup(this);
    for(int i=0;i<5;i++)
    {
        loopActions[i]->setCheckable(true);
        group->addAction(loopActions[i]);
    }

    QSettings setting("./Setting.ini",QSettings::IniFormat);
    int index = setting.value("PlaybackModel",1).toInt();
    loopActions[index]->setChecked(true);

    loadPlayList("default.list");

    connect(m_play,&QAction::triggered,this,&MediaListView::play);
    connect(addFile,&QAction::triggered,this,&MediaListView::addFile);
    connect(addFolder,&QAction::triggered,this,&MediaListView::addFolder);
    connect(load,&QAction::triggered,this,&MediaListView::loadPlaylist);
    connect(save,&QAction::triggered,this,&MediaListView::savePlaylist);
    connect(m_deleteSelect,&QAction::triggered,this,&MediaListView::deleteSelect);
    connect(clearPlayList,&QAction::triggered,this,&MediaListView::clearPlaylist);
    connect(clearInvalidfiles,&QAction::triggered,this,&MediaListView::clearInvalidFiles);
    connect(loopMode,&QMenu::triggered,this,&MediaListView::loopMode);
    connect(m_openFolder,&QAction::triggered,this,&MediaListView::openFolder);
    connect(this,&MediaListView::customContextMenuRequested,this,&MediaListView::customContext);

重写自定义菜单函数,如果右键的时候没有选中任何索引,需要把播放,删除,打开目录设置为不可点击

void MediaListView::customContext(const QPoint &pos)
{
    bool isEnable=!selectionModel()->selectedIndexes().isEmpty();

    m_play->setEnabled(isEnable);
    m_deleteSelect->setEnabled(isEnable);
    m_openFolder->setEnabled(isEnable);

    m_menu->exec(QCursor::pos());
}

插入数据,用于VideoWidget按钮插入

void MediaListView::insert(const QUrl &url)
{
    m_model->insert(url);
    auto index = QModelIndex();
    index = m_model->index(m_model->rowCount(index)-1,0,index);
    setCurrentIndex(index);
}

选择文件夹,便利文件夹下面所有多媒体文件,把路径插入列表

void MediaListView::addFolder()
{
    QString path = QFileDialog::getExistingDirectory(nullptr,"Select Video Directory");
    QDir dir(path);
    QStringList filter = m_fileFilter?m_fileFilter->getFilterAll():QStringList();
    auto list = dir.entryInfoList(filter,QDir::Files|QDir::Readable, QDir::Name);
    foreach (auto p, list)
    {
       m_model->insert(QUrl::fromLocalFile(p.filePath()));
    }
}

读取列表,简单的文件读取

void MediaListView::loadPlaylist()
{
    auto fileName = QFileDialog::getOpenFileName(nullptr,"Select list","","*.list");
    if(fileName.isEmpty())
    {
        return;
    }
    loadPlayList(fileName);
}

void MediaListView::loadPlayList(QString fileName)
{
    QFile file(fileName);
    if(!file.open(QIODevice::Text|QIODevice::ReadOnly))
    {
        qDebug()<<QString("not open listInfo file ");
        return;
    }
    QTextStream ts(&file);
    while(!ts.atEnd())
    {
       m_model->insert(ts.readLine());
    }
    file.close();
}

保存列表,简单的文件写入

void MediaListView::savePlaylist()
{
    auto fileName = QFileDialog::getSaveFileName(nullptr,"save list","","*.list");
    if(fileName.isEmpty())
    {
        return;
    }
    savePlayList(fileName);
}

void MediaListView::savePlayList(QString fileName)
{
    QFile file(fileName);
    if(!file.open(QIODevice::Text|QIODevice::WriteOnly))
    {
        qDebug()<<QString("not create listInfo file ");
       return;
    }
    QTextStream ts(&file);
    auto modelIndex = QModelIndex();
    int count=m_model->rowCount(modelIndex);
    int index=0;

    while(index<count)
    {
        ts<<m_model->media(m_model->index(index,0,modelIndex)).canonicalUrl().toString()<<endl;
        index++;
    }
    file.close();
}

删除选中项,删除的时候需要从后面的索引删起,3,2,1  ,如果删除了当前正在播放的,需要结束播放

bool modelSort(const QModelIndex &a, const QModelIndex &b)
{
    return a.row()> b.row();
}
void MediaListView::deleteSelect()
{
    auto indexs = selectedIndexes();
    qSort(indexs.begin(),indexs.end(),modelSort);
    foreach (auto index, indexs) {
        model()->removeRow(index.row());
        if(index ==m_model->currentIndex())
        {
            emit deleteIndex();
        }
    }
}

清空列表,直接删除所有项,并通知结束播放

void MediaListView::clearPlaylist()
{
    model()->removeRows(0,model()->rowCount(QModelIndex()),QModelIndex());
    emit deleteIndex();
}

清空无用项,简单的判断一下文件是否存在

void MediaListView::clearInvalidFiles()
{
    auto index = QModelIndex();
    int count =m_model->rowCount(index);

    for(int i=count-1;i>=0;i--)
    {
        auto url =m_model->media(m_model->index(i,0,index)).canonicalUrl();
        if(url.isLocalFile())
        {
            auto fileName = url.toString();
            fileName.replace("file:///","");
            QFile file(fileName);
            if(!file.exists())
            {
               m_model->removeRow(i);
            }
        }
    }
}

打开文件目录,使用 QDesktopServices 打开资源管理器

void MediaListView::openFolder()
{
    auto url =m_model->media(currentIndex()).canonicalUrl();
    if(url.isLocalFile())
    {
        QFileInfo info(url.path());
        QDesktopServices::openUrl(QUrl::fromLocalFile( info.dir().path()));
    }
}

设置播放模式,设置后保存到Setting.ini文件

void MediaListView::loopMode(QAction *action)
{
    auto text = action->text();

    for(int i=0;i<5;i++)
    {
        if(text == m_playModeKey[i])
        {
            m_model->setPlaybackMode(m_playModeValue[i]);
            QSettings setting("./Setting.ini",QSettings::IniFormat);
            setting.setValue("PlaybackModel",i);
            break;
        }
    }
}

窗口初始化的时候加载Setting.ini文件

    QSettings setting("./Setting.ini",QSettings::IniFormat);
    int index = setting.value("PlaybackModel",1).toInt();
    loopActions[index]->setChecked(true);

 

 

 

 

 

 

完整代码

#ifndef MEDIALISTVIEW_H
#define MEDIALISTVIEW_H

#include <QListView>
#include <QMediaPlayer>
#include "medialistmodel.h"

QT_BEGIN_NAMESPACE
class QAction;
class FileFilter;
class MediaListModel;
QT_END_NAMESPACE

class MediaListView : public QListView
{
    Q_OBJECT
public:
    explicit MediaListView(QWidget *parent = nullptr);
    void setFileFilter(FileFilter *filter);
    void insert(const QUrl &url);
    void setPlayIndex(const QModelIndex &index);
    QMediaContent media(const QModelIndex &index)const;
signals:
    void playIndex(const QModelIndex &index);
    void deleteIndex();

public slots:
    void next();
    void previous();
    void mediaStatusChanged(QMediaPlayer::MediaStatus status);

private slots:
    void customContext(const QPoint &pos);
    void play();
    void addFile();
    void addFolder();
    void loadPlaylist();
    void savePlaylist();
    void deleteSelect();
    void clearPlaylist();
    void clearInvalidFiles();
    void loopMode(QAction *action);
    void openFolder();
    void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles = QVector<int>());

    // QWidget interface
protected:
    void mousePressEvent(QMouseEvent *event);

private:
    void loadPlayList(QString fileName);
    void savePlayList(QString fileName);

private:
    QMenu *m_menu;
    QString m_playModeKey[5];
    MediaListModel::PlaybackMode m_playModeValue[5];
    QAction *m_play;
    QAction *m_deleteSelect;
    QAction *m_openFolder;

    MediaListModel *m_model;
    FileFilter *m_fileFilter;
};

#endif // MEDIALISTVIEW_H
#include "medialistview.h"
#include <QMenu>
#include <QMouseEvent>
#include <QDebug>
#include <QAction>
#include <QFileDialog>
#include <QDesktopServices>
#include <QSettings>
#include "filefilter.h"
MediaListView::MediaListView(QWidget *parent) : QListView(parent)
{
m_model = new MediaListModel(this);
this->setModel(m_model);
setEditTriggers(QAbstractItemView::NoEditTriggers);
setSelectionMode(QAbstractItemView::ExtendedSelection);
setContextMenuPolicy(Qt::CustomContextMenu);
m_playModeKey[0] = QStringLiteral("顺序播放");
m_playModeKey[1] = QStringLiteral("单个播放");
m_playModeKey[2] = QStringLiteral("随机播放");
m_playModeKey[3] = QStringLiteral("单个循环");
m_playModeKey[4] = QStringLiteral("列表循环");
m_playModeValue[0]=MediaListModel::Sequential;
m_playModeValue[1]=MediaListModel::CurrentItemOnce;
m_playModeValue[2]=MediaListModel::Random;
m_playModeValue[3]=MediaListModel::CurrentItemInLoop;
m_playModeValue[4]=MediaListModel::Loop;
m_menu = new QMenu();
m_play = m_menu->addAction(QStringLiteral("播放"));
auto addFile = m_menu->addAction(QStringLiteral("添加文件"));
auto addFolder = m_menu->addAction(QStringLiteral("添加文件夹"));
auto load = m_menu->addAction(QStringLiteral("载入播放列表"));
auto save = m_menu->addAction(QStringLiteral("保存播放列表"));
m_deleteSelect = m_menu->addAction(QStringLiteral("删除选中项"));
auto clearPlayList = m_menu->addAction(QStringLiteral("清空播放列表"));
auto clearInvalidfiles = m_menu->addAction(QStringLiteral("清空无效文件"));
auto loopMode = m_menu->addMenu(QStringLiteral("循环模式"));
m_openFolder = m_menu->addAction(QStringLiteral("打开文件目录"));
QAction* loopActions[5];
loopActions[0] = loopMode->addAction(m_playModeKey[0]);
loopActions[1] =loopMode->addAction(m_playModeKey[1]);
loopActions[2] =loopMode->addAction(m_playModeKey[2]);
loopActions[3] =loopMode->addAction(m_playModeKey[3]);
loopActions[4] =loopMode->addAction(m_playModeKey[4]);
QActionGroup *group = new QActionGroup(this);
for(int i=0;i<5;i++)
{
loopActions[i]->setCheckable(true);
group->addAction(loopActions[i]);
}
QSettings setting("./Setting.ini",QSettings::IniFormat);
int index = setting.value("PlaybackModel",1).toInt();
loopActions[index]->setChecked(true);
loadPlayList("default.list");
connect(m_play,&QAction::triggered,this,&MediaListView::play);
connect(addFile,&QAction::triggered,this,&MediaListView::addFile);
connect(addFolder,&QAction::triggered,this,&MediaListView::addFolder);
connect(load,&QAction::triggered,this,&MediaListView::loadPlaylist);
connect(save,&QAction::triggered,this,&MediaListView::savePlaylist);
connect(m_deleteSelect,&QAction::triggered,this,&MediaListView::deleteSelect);
connect(clearPlayList,&QAction::triggered,this,&MediaListView::clearPlaylist);
connect(clearInvalidfiles,&QAction::triggered,this,&MediaListView::clearInvalidFiles);
connect(loopMode,&QMenu::triggered,this,&MediaListView::loopMode);
connect(m_openFolder,&QAction::triggered,this,&MediaListView::openFolder);
connect(this,&MediaListView::customContextMenuRequested,this,&MediaListView::customContext);
connect(m_model,&MediaListModel::dataChanged,this,&MediaListView::dataChanged);
}
void MediaListView::setFileFilter(FileFilter *filter)
{
m_fileFilter = filter;
}
void MediaListView::insert(const QUrl &url)
{
m_model->insert(url);
auto index = QModelIndex();
index = m_model->index(m_model->rowCount(index)-1,0,index);
setCurrentIndex(index);
}
void MediaListView::setPlayIndex(const QModelIndex &index)
{
m_model->setPlayIndex(index.row());
}
QMediaContent MediaListView::media(const QModelIndex &index) const
{
return m_model->media(index);
}
void MediaListView::next()
{
auto index =m_model->currentIndex();
index = model()->index(index.row()+1,0);
if(index.row()==-1 &&m_model->playbackMode() == MediaListModel::Loop)
{
index=m_model->index(0,0);
}
setCurrentIndex(index);
emit playIndex(index);
}
void MediaListView::previous()
{
auto index =m_model->currentIndex();
index = model()->index(index.row()-1,0);
if(index.row()==-1 &&m_model->playbackMode() == MediaListModel::Loop)
{
index=model()->index(model()->rowCount(QModelIndex())-1,0);
}
setCurrentIndex(index);
emit playIndex(index);
}
void MediaListView::mediaStatusChanged(QMediaPlayer::MediaStatus status)
{
if(status != QMediaPlayer::EndOfMedia)
{
return;
}
QModelIndex index =m_model->currentIndex();
switch(m_model->playbackMode())
{
case MediaListModel::Random:
do
{
index =m_model->index(rand()%m_model->rowCount(),0);
}while(index ==m_model->currentIndex());
case MediaListModel::CurrentItemInLoop:
setCurrentIndex(index);
emit playIndex(index);
break;
case MediaListModel::Sequential:
case MediaListModel::Loop:
next();
break;
}
}
void MediaListView::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles)
{
Q_UNUSED(topLeft);
Q_UNUSED(bottomRight);
Q_UNUSED(roles);
savePlayList("default.list");
}
void MediaListView::customContext(const QPoint &pos)
{
bool isEnable=!selectionModel()->selectedIndexes().isEmpty();
m_play->setEnabled(isEnable);
m_deleteSelect->setEnabled(isEnable);
m_openFolder->setEnabled(isEnable);
m_menu->exec(QCursor::pos());
}
void MediaListView::play()
{
emit playIndex(currentIndex());
}
void MediaListView::addFile()
{
QString filter=m_fileFilter?m_fileFilter->getFilterString():QString();
QUrl url = QFileDialog::getOpenFileUrl(nullptr,"select video file",QUrl(),filter);
if(url.isLocalFile())
{
m_model->insert(url);
}
}
void MediaListView::addFolder()
{
QString path = QFileDialog::getExistingDirectory(nullptr,"Select Video Directory");
QDir dir(path);
QStringList filter = m_fileFilter?m_fileFilter->getFilterAll():QStringList();
auto list = dir.entryInfoList(filter,QDir::Files|QDir::Readable, QDir::Name);
foreach (auto p, list)
{
m_model->insert(QUrl::fromLocalFile(p.filePath()));
}
}
void MediaListView::loadPlaylist()
{
auto fileName = QFileDialog::getOpenFileName(nullptr,"Select list","","*.list");
if(fileName.isEmpty())
{
return;
}
loadPlayList(fileName);
}
void MediaListView::savePlaylist()
{
auto fileName = QFileDialog::getSaveFileName(nullptr,"save list","","*.list");
if(fileName.isEmpty())
{
return;
}
savePlayList(fileName);
}
bool modelSort(const QModelIndex &a, const QModelIndex &b)
{
return a.row()> b.row();
}
void MediaListView::deleteSelect()
{
auto indexs = selectedIndexes();
qSort(indexs.begin(),indexs.end(),modelSort);
foreach (auto index, indexs) {
model()->removeRow(index.row());
if(index ==m_model->currentIndex())
{
emit deleteIndex();
}
}
}
void MediaListView::clearPlaylist()
{
model()->removeRows(0,model()->rowCount(QModelIndex()),QModelIndex());
emit deleteIndex();
}
void MediaListView::clearInvalidFiles()
{
auto index = QModelIndex();
int count =m_model->rowCount(index);
for(int i=count-1;i>=0;i--)
{
auto url =m_model->media(m_model->index(i,0,index)).canonicalUrl();
if(url.isLocalFile())
{
auto fileName = url.toString();
fileName.replace("file:///","");
QFile file(fileName);
if(!file.exists())
{
m_model->removeRow(i);
}
}
}
}
void MediaListView::loopMode(QAction *action)
{
auto text = action->text();
for(int i=0;i<5;i++)
{
if(text == m_playModeKey[i])
{
m_model->setPlaybackMode(m_playModeValue[i]);
QSettings setting("./Setting.ini",QSettings::IniFormat);
setting.setValue("PlaybackModel",i);
break;
}
}
}
void MediaListView::openFolder()
{
auto url =m_model->media(currentIndex()).canonicalUrl();
if(url.isLocalFile())
{
QFileInfo info(url.path());
QDesktopServices::openUrl(QUrl::fromLocalFile( info.dir().path()));
}
}
void MediaListView::mousePressEvent(QMouseEvent *event)
{
auto index = indexAt(event->pos());
if(index.row()==-1)
{
setCurrentIndex(index);
}
QListView::mousePressEvent(event);
}
void MediaListView::loadPlayList(QString fileName)
{
QFile file(fileName);
if(!file.open(QIODevice::Text|QIODevice::ReadOnly))
{
qDebug()<<QString("not open listInfo file ");
return;
}
QTextStream ts(&file);
while(!ts.atEnd())
{
m_model->insert(ts.readLine());
}
file.close();
}
void MediaListView::savePlayList(QString fileName)
{
QFile file(fileName);
if(!file.open(QIODevice::Text|QIODevice::WriteOnly))
{
qDebug()<<QString("not create listInfo file ");
return;
}
QTextStream ts(&file);
auto modelIndex = QModelIndex();
int count=m_model->rowCount(modelIndex);
int index=0;
while(index<count)
{
ts<<m_model->media(m_model->index(index,0,modelIndex)).canonicalUrl().toString()<<endl;
index++;
}
file.close();
}

 

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

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

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

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

(0)


相关推荐

  • stm32蓝牙模块控制小车_如何让电脑有蓝牙功能

    stm32蓝牙模块控制小车_如何让电脑有蓝牙功能重要声明看过我前面51小车博客的都知道我是软件工程专业的,对于硬件方面都是因为感兴趣自学的,这不,因为今年寒假放假比较早,趁这个时间学习了STM32相关知识,经过近一个月的学习对于STM32算是入门了,为了检验自己的学习效果,我决定就着51小车的架子用STM32试试,经过一个下午的忙活算是成功了!!!所以再来和大家分享一下。所需知识贮备相信看到这篇文章的小伙伴都是有相关基础的,这里只是给和我一样自学的小伙伴提个醒。动手之前你需要这些:硬件电路连接相关能力C语言基础能力STM32定时器、中断、串

  • 【SQL Server】关于报错“备份集中的数据库备份与现有的数据库”xxx”不同”的解决方案

    【SQL Server】关于报错“备份集中的数据库备份与现有的数据库”xxx”不同”的解决方案在做数据库备份与还原的过程中可能因为一下小的细节导致通过备份文件还原的时候报错:备份集中的数据库备份与现有的数据库"xxx"不同导致这种报错的原因是:备份文件与现有数据库的结构不一致因此要恢复数据库就需要去“选项”中勾选“覆盖现有数据库”这样备份就搞定了 …

  • page对象的使用及常见方法

    page对象的使用及常见方法page对象的使用及常见方法制作人:全心全意page对象代表JSP本身,只有在JSP页面内才是合法的。page对象本质上是包含当前Servlet接口引用的变量,可以看作是this关键字的别名。p

  • 群体遗传学—admixture软件快速群体分群

    群体遗传学—admixture软件快速群体分群群体遗传学中测的很多个个体,得到了最终的SNPvcf文件,需要将其分成群体,看那几个物种聚在一起,一般使用的软件就是STRUCTURE,但是STREUTURE运行速度极慢,后面frappe软件提升了速度,但是也不是很快;admixture凭借其运算速度,成为了主流的分析软件。admixture软件一共分为5步:#step1/USER/zhusitao/Software/vcft

    2022年10月28日
  • 视频行为识别检测综述 IDT TSN CNN-LSTM C3D CDC R-C3D

    视频行为识别检测综述 IDT TSN CNN-LSTM C3D CDC R-C3D本文github地址VideoAnalysis之ActionRecognition(行为识别)行为识别就是对时域预先分割好的序列判定其所属行为动作的类型,即“读懂行为”。[行为检测|论文解读]行为检测调研综述较新基于DeepLearning的视频识别技术科研成果—-中国科学院深圳先进技术研究院面向人体姿态行为理解的深度学习方法CVPR2014Tut…

  • win10无法生成常规子目录下的列表_windows无法更新怎么办

    win10无法生成常规子目录下的列表_windows无法更新怎么办1.问题背景Win10只要系统安装好之后会自动生成一系列的系统文件夹,如下:这类文件夹比较特殊,它们比普通文件夹多一个“位置”选项卡,如默认的“下载”文件夹,edge和chrome浏览器会默认下载到这个文件夹,所以新系统拿到手之后,往往都需要将这些文件夹修改到其他硬盘上,不然C盘会因为下载文件的不断增多而变得异常臃肿:如果这个时候你手抖了,需要修改……………

发表回复

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

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