QT 播放器之列表
列表只需要顯示字符串就行。直接選擇使用 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_NAMESPACEclass 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(); }?
總結
 
                            
                        - 上一篇: 操作系统课程设计之Pintos
- 下一篇: oracle之单行函数之多表查询值之课后
