Python MP3播放器(二) 这次用QTableView在界面中添加了歌曲列表,实现双击播放,设置各列列宽,设置了单元格不可编辑

Python MP3播放器(二) 这次用QTableView在界面中添加了歌曲列表,实现双击播放,设置各列列宽,设置了单元格不可编辑_第1张图片
逻辑主程序:

from PyQt5.QtWidgets import QMainWindow, QApplication, QFileDialog, QMessageBox, QDialog, QPushButton, QAbstractItemView
from PyQt5.QtCore import QUrl, Qt
from PyQt5.QtGui import QStandardItemModel, QStandardItem
from Ui_playerUi3 import Ui_MainWindow
from Mp3Info import GetMp3Info
from PyQt5.QtMultimedia import QMediaPlayer, QMediaPlaylist, QMediaContent
import sys
import os


class My(QMainWindow, Ui_MainWindow):
    def __init__(self):
        super().__init__()
        win = self.setupUi(self)
        self.player = QMediaPlayer()  # 创建播放器
        self.playList = QMediaPlaylist()  # 创建播放列表
        self.playList.setPlaybackMode(QMediaPlaylist.Loop)  # 设置循环播放
        self.determineExistPlayDir()
        self.singalAndSlot()
        self.setWindowFlags(Qt.WindowCloseButtonHint)  # 取消窗口最大化和最小化
        self.songListSet()

    def songListSet(self):
        '''在界面显示歌曲列表'''
        self.model = QStandardItemModel(0, 4)  # 创造数据模型,0行,4列
        self.model.setHorizontalHeaderLabels(['歌曲', '歌手', '专辑', '时长'])  # 设置标题
        if self.playList.mediaCount():  # 添加数据
            for index in range(self.playList.mediaCount()):
                path = self.playList.media(index).canonicalUrl().path()[1:]
                info = GetMp3Info(path)
                self.model.appendRow([  # 添加一行数据
                    QStandardItem(info.title),
                    QStandardItem(info.artist),
                    QStandardItem(info.album),
                    QStandardItem(info.length)
                ])
        self.songList.setModel(self.model)  # 把数据添加至QtableView中
        self.songList.setColumnWidth(0, 350)  # 设置第1列列宽
        self.songList.setColumnWidth(1, 200)  # 设置第2列列宽
        self.songList.setColumnWidth(2, 250)  # 设置第3列列宽
        self.songList.setColumnWidth(3, 158)  # 设置第4列列宽
        self.songList.setEditTriggers(
            QAbstractItemView.NoEditTriggers)  # 设置不可编辑单元格

    def singalAndSlot(self):
        '''这里汇聚了所有的信号和槽'''
        self.nextSong.clicked.connect(self.nextS)
        self.preSong.clicked.connect(self.preS)
        self.startStop.clicked.connect(self.startOrStop)
        self.songDir.clicked.connect(self.writeDir)
        self.songList.doubleClicked.connect(self.otherSong)

    def otherSong(self):
        '''双击后播放'''
        index = self.songList.currentIndex().row()  # 获取双击所在行
        self.playList.setCurrentIndex(index)
        self.staShow()

    def noSongsMessage(self):
        mess = QMessageBox.warning(self,
                                   "温馨提示",
                                   '列表中没有歌曲,请点击歌曲目录添加歌曲!',
                                   QMessageBox.Yes)

    def determineExistPlayDir(self):
        '''判断是否存在配置文件,配置文件中是否存有播放目录'''
        try:
            with open('play.ini', 'r') as f:
                self.url = f.read()
        except:
            self.url = ''
        self.addSongsToPlaylist()

    def writeDir(self):
        '''选取要播放的歌曲目录'''
        self.url = QFileDialog.getExistingDirectory(self,
                                                    "选取文件夹",
                                                    "./")
        with open('play.ini', 'w') as f:
            f.write(self.url)
        self.addSongsToPlaylist()
        self.songListSet()

    def addSongsToPlaylist(self):
        self.getSongs()
        self.playList.clear()
        if self.allSong:
            for i in self.allSong:
                self.playList.addMedia(QMediaContent(
                    QUrl.fromLocalFile(i)))  # 把所有歌曲添加到列表中
            self.player.setPlaylist(self.playList)
            self.player.play()  # 开始播放
            songInfo = self.getSongInfo()
            self.statusbar.showMessage(songInfo.title)

    def startOrStop(self):
        '''播放按键控制'''
        if not self.allSong:
            self.noSongsMessage()
        else:
            if self.player.state() == 1: #判断播放状态,1表示播放中,2表示暂停
                self.player.pause()
                self.statusbar.showMessage('暂停')
                self.startStop.setText('播放')
            elif self.player.state() == 2:
                self.player.play()
                self.staShow()
                self.startStop.setText('暂停')

    def staShow(self):
        '''显示歌曲名'''
        if self.allSong:
            songInfo = self.getSongInfo()
            self.statusbar.showMessage(songInfo.title)

    def nextS(self):
        '''下一首'''
        if not self.allSong:
            self.noSongsMessage()
        else:
            self.playList.next()
            self.staShow()

    def preS(self):
        '''上一首'''
        if not self.allSong:
            self.noSongsMessage()
        else:
            self.playList.previous()
            self.staShow()

    def getSongInfo(self):
        '''获取歌曲信息
        info:歌曲信息对象
        '''
        path = self.player.currentMedia().canonicalUrl().path()[
            1:]  # 获取当前播放曲目路径
        info = GetMp3Info(path)
        return info

    def getSongs(self):
        '''
        获取文件夹内所有的歌曲
        '''
        self.allSong = []
        for root, dirs, files in os.walk(self.url):
            for file in files:
                if file[-3:] == 'mp3':#如果是MP3文件则加入至列表
                    self.allSong.append(os.path.join(root, file))


if __name__ == "__main__":
    app = QApplication(sys.argv)
    w = My()
    w.show()
    sys.exit(app.exec())

获取Mp3信息:

from mutagen.mp3 import MP3
from mutagen.id3 import ID3, APIC, TIT2, TPE1, TALB
import os


class GetMp3Info():
    '''获取歌曲信息'''
    def __init__(self, path):
        try:
            songFile = ID3(path)
        except:
            self.title = os.path.basename(path).split('.')[0]
            self.picData=''
            self.artist=''
            self.album=''
            self.length=''
        else:
            self.getTitle(songFile, path)
            self.getArtist(songFile)
            self.getAlbum(songFile)
            self.getPicData(songFile)
            songFile=MP3(path)
            self.getLength(songFile)

            

    def getTitle(self, songFile, path):
        '''获取歌曲名
        songFile:文件对象
        path:文件地址
        '''
        try:
            self.title = str(songFile['TIT2'])
        except:
            filename = os.path.basename(path)  # 从地址中获取文件名
            self.title = filename.split('.')[0]  # 去掉文件名后缀

    def getArtist(self,songFile):
        '''获取歌手名
        songFile:文件对象
        '''
        try:
            self.artist=str(songFile['TPE1'])
        except:
            self.artist=''

    def getAlbum(self,songFile):
        '''获取专辑名
        songFile:文件对象
        '''
        try:
            self.album=str(songFile['TALB'])
        except:
            self.album=''

    def getLength(self,songFile):
        '''获取文件播放时时长'''
        timeLength = int(songFile.info.length)
        mintime = timeLength//60  #转换为分钟
        sectime = timeLength % 60 #剩余的转换为秒
        if sectime < 10:
            sectime='0'+ str(sectime)
        else:
            sectime=str(sectime)
        self.length=str(mintime)+":"+sectime

    def getPicData(self,songFile):
        try:
            self.picData=songFile['APIC:Cover']
        except:
            self.picData=''



def SetMp3Info(path,info):
    songFile = ID3(path)
    songFile['APIC'] = APIC(  # 插入封面
        encoding=3,
        mime='image/jpeg',
        type=3,
        desc=u'Cover',
        data=info['picData']
    )
    songFile['TIT2'] = TIT2(  # 插入歌名
        encoding=3,
        text=info['title']
    )
    songFile['TPE1'] = TPE1(  # 插入第一演奏家、歌手、等
        encoding=3,
        text=info['artist']
    )
    songFile['TALB'] = TALB(  # 插入专辑名
        encoding=3,
        text=info['album']
    )
    songFile.save()



if __name__=='__main__':
    path='侧脸-于果.mp3'
    song=GetMp3Info(path)
    print(song.title,song.album,song.artist,song.length,song.picData)
    print(song.title)

UI:

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'g:\Mp3player\playerUi3.ui'
#
# Created by: PyQt5 UI code generator 5.12.2
#
# WARNING! All changes made in this file will be lost!

from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.setEnabled(True)
        MainWindow.resize(1005, 420)
        MainWindow.setMinimumSize(QtCore.QSize(0, 0))
        MainWindow.setMaximumSize(QtCore.QSize(10000, 10000))
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.layoutWidget = QtWidgets.QWidget(self.centralwidget)
        self.layoutWidget.setGeometry(QtCore.QRect(320, 360, 263, 32))
        self.layoutWidget.setObjectName("layoutWidget")
        self.horizontalLayout = QtWidgets.QHBoxLayout(self.layoutWidget)
        self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.preSong = QtWidgets.QPushButton(self.layoutWidget)
        self.preSong.setMinimumSize(QtCore.QSize(60, 30))
        self.preSong.setMaximumSize(QtCore.QSize(60, 30))
        self.preSong.setToolTipDuration(0)
        self.preSong.setStyleSheet("background:white; border:0px;border-radius:10px")
        self.preSong.setObjectName("preSong")
        self.horizontalLayout.addWidget(self.preSong)
        self.startStop = QtWidgets.QPushButton(self.layoutWidget)
        self.startStop.setMinimumSize(QtCore.QSize(60, 30))
        self.startStop.setMaximumSize(QtCore.QSize(60, 30))
        self.startStop.setToolTipDuration(0)
        self.startStop.setStyleSheet("background:white; border:0px;border-radius:10px")
        self.startStop.setObjectName("startStop")
        self.horizontalLayout.addWidget(self.startStop)
        self.nextSong = QtWidgets.QPushButton(self.layoutWidget)
        self.nextSong.setMinimumSize(QtCore.QSize(60, 30))
        self.nextSong.setMaximumSize(QtCore.QSize(60, 30))
        self.nextSong.setToolTipDuration(0)
        self.nextSong.setStyleSheet("background:white; border:0px;border-radius:10px")
        self.nextSong.setObjectName("nextSong")
        self.horizontalLayout.addWidget(self.nextSong)
        self.songDir = QtWidgets.QPushButton(self.layoutWidget)
        self.songDir.setMinimumSize(QtCore.QSize(60, 30))
        self.songDir.setMaximumSize(QtCore.QSize(60, 30))
        self.songDir.setToolTipDuration(0)
        self.songDir.setStyleSheet("background:white; border:0px;border-radius:10px")
        self.songDir.setObjectName("songDir")
        self.horizontalLayout.addWidget(self.songDir)
        self.songList = QtWidgets.QTableView(self.centralwidget)
        self.songList.setGeometry(QtCore.QRect(0, 0, 1011, 351))
        self.songList.setLineWidth(1)
        self.songList.setMidLineWidth(0)
        self.songList.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
        self.songList.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
        self.songList.setTextElideMode(QtCore.Qt.ElideLeft)
        self.songList.setShowGrid(False)
        self.songList.setObjectName("songList")
        MainWindow.setCentralWidget(self.centralwidget)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "Mp3Player"))
        self.preSong.setText(_translate("MainWindow", "上一首"))
        self.startStop.setText(_translate("MainWindow", "暂停"))
        self.nextSong.setText(_translate("MainWindow", "下一首"))
        self.songDir.setText(_translate("MainWindow", "歌曲目录"))

你可能感兴趣的:(Python)