一:目的
(1)获取音乐文件,播放本地音乐,可切换音乐,暂停音乐,获取音乐播放总时间,选择单曲循环或者列表循环;
(2)自由设置音乐的音量;
(3)显示对应播放音乐的歌词;
演示:
二:利用QT-Tool,首先设计界面(UI)
(1)ui文件如下:music.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>685</width>
<height>560</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="mouseTracking">
<bool>true</bool>
</property>
<property name="tabletTracking">
<bool>true</bool>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QGroupBox" name="groupBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>180</width>
<height>16777215</height>
</size>
</property>
<property name="cursor">
<cursorShape>ArrowCursor</cursorShape>
</property>
<property name="mouseTracking">
<bool>false</bool>
</property>
<property name="layoutDirection">
<enum>Qt::LeftToRight</enum>
</property>
<property name="autoFillBackground">
<bool>false</bool>
</property>
<property name="title">
<string>曲目</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
<property name="checkable">
<bool>false</bool>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<property name="sizeConstraint">
<enum>QLayout::SetDefaultConstraint</enum>
</property>
<item row="0" column="1">
<widget class="QPushButton" name="pushButton">
<property name="minimumSize">
<size>
<width>0</width>
<height>30</height>
</size>
</property>
<property name="text">
<string>上级</string>
</property>
<property name="checkable">
<bool>false</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item row="2" column="0" colspan="2">
<widget class="QListWidget" name="listWidget">
<property name="minimumSize">
<size>
<width>160</width>
<height>0</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::WinPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QPushButton" name="device_ret">
<property name="minimumSize">
<size>
<width>0</width>
<height>30</height>
</size>
</property>
<property name="text">
<string>音频设备</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="0" column="1">
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>播放显示</string>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="3" column="0">
<widget class="QPushButton" name="next_music">
<property name="minimumSize">
<size>
<width>0</width>
<height>30</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>40</width>
<height>40</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset>
<activeoff>:/put1/IMG/按钮/下首按钮.png</activeoff>
</iconset>
</property>
<property name="iconSize">
<size>
<width>40</width>
<height>40</height>
</size>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="QPushButton" name="last_music">
<property name="minimumSize">
<size>
<width>0</width>
<height>30</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>40</width>
<height>40</height>
</size>
</property>
<property name="baseSize">
<size>
<width>80</width>
<height>80</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">QPushButton {"
"background-color: green;"
"font: bold 20px;"
"border-width: 1px;"
"border-radius: 40px;"
"color: white;"
}</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset>
<activeoff>:/put1/IMG/按钮/上首按钮.png</activeoff>
</iconset>
</property>
<property name="iconSize">
<size>
<width>40</width>
<height>40</height>
</size>
</property>
</widget>
</item>
<item row="0" column="0" colspan="10">
<widget class="QLabel" name="jumpgif">
<property name="minimumSize">
<size>
<width>0</width>
<height>40</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>50</height>
</size>
</property>
<property name="sizeIncrement">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="baseSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::Panel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Sunken</enum>
</property>
<property name="text">
<string><html><head/><body><p align="center">展示GIF</p></body></html></string>
</property>
</widget>
</item>
<item row="2" column="8">
<widget class="QLabel" name="timeshow">
<property name="minimumSize">
<size>
<width>55</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>60</width>
<height>60</height>
</size>
</property>
<property name="text">
<string><html><head/><body><p>0:0/0:0</p></body></html></string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QPushButton" name="play_stop_music">
<property name="minimumSize">
<size>
<width>0</width>
<height>30</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>40</width>
<height>40</height>
</size>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset>
<activeon>:/put1/IMG/按钮/播放按钮.png</activeon>
</iconset>
</property>
<property name="iconSize">
<size>
<width>40</width>
<height>40</height>
</size>
</property>
<property name="checkable">
<bool>false</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
<property name="autoRepeat">
<bool>false</bool>
</property>
<property name="autoExclusive">
<bool>false</bool>
</property>
</widget>
</item>
<item row="2" column="0" colspan="8">
<widget class="QSlider" name="horizontalSlider">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::NoTicks</enum>
</property>
</widget>
</item>
<item row="2" column="9" rowspan="2">
<widget class="QLabel" name="label_3">
<property name="styleSheet">
<string notr="true">image: url(:/put1/IMG/独家.png);</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="3" column="8">
<widget class="QLabel" name="soundvalue">
<property name="maximumSize">
<size>
<width>50</width>
<height>50</height>
</size>
</property>
<property name="text">
<string><html><head/><body><p>0</p></body></html></string>
</property>
</widget>
</item>
<item row="3" column="6" colspan="2">
<widget class="QSlider" name="verticalSlider">
<property name="styleSheet">
<string notr="true"/>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="3" column="3" colspan="2">
<widget class="QComboBox" name="comboBox">
<property name="minimumSize">
<size>
<width>0</width>
<height>40</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>100</width>
<height>16777215</height>
</size>
</property>
<item>
<property name="text">
<string>单曲循环</string>
</property>
<property name="icon">
<iconset>
<activeon>:/put1/IMG/next.png</activeon>
</iconset>
</property>
</item>
<item>
<property name="text">
<string>列表循环</string>
</property>
<property name="icon">
<iconset>
<activeon>:/put1/IMG/循环.jpg</activeon>
</iconset>
</property>
</item>
</widget>
</item>
<item row="1" column="0" colspan="3">
<widget class="QLabel" name="showgdance0">
<property name="minimumSize">
<size>
<width>132</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">background-color: rgb(208, 208, 208);</string>
</property>
<property name="frameShape">
<enum>QFrame::WinPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<property name="text">
<string><html><head/><body><p align="center">GIF跳动</p></body></html></string>
</property>
</widget>
</item>
<item row="1" column="8" colspan="2">
<widget class="QLabel" name="showgdance1">
<property name="minimumSize">
<size>
<width>132</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">background-color: rgb(208, 208, 208);</string>
</property>
<property name="frameShape">
<enum>QFrame::WinPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<property name="text">
<string><html><head/><body><p align="center">GIF跳动</p></body></html></string>
</property>
</widget>
</item>
<item row="3" column="5">
<widget class="QLabel" name="label">
<property name="enabled">
<bool>true</bool>
</property>
<property name="frameShape">
<enum>QFrame::Panel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Sunken</enum>
</property>
<property name="text">
<string>音量设置:</string>
</property>
</widget>
</item>
<item row="1" column="3" colspan="5">
<widget class="QScrollArea" name="scrollArea">
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>183</width>
<height>343</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QTextEdit" name="textEdit">
<property name="maximumSize">
<size>
<width>16777215</width>
<height>50</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">background-color: rgba(255, 255, 255, 0.1);</string>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="html">
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
p, li { white-space: pre-wrap; }
</style></head><body style=" font-family:'SimSun'; font-size:9pt; font-weight:400; font-style:normal;">
<p align="center" style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html></string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QTextEdit" name="textEdit_2">
<property name="maximumSize">
<size>
<width>16777215</width>
<height>50</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">background-color: rgba(255, 255, 255, 0.1);</string>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="html">
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
p, li { white-space: pre-wrap; }
</style></head><body style=" font-family:'SimSun'; font-size:9pt; font-weight:400; font-style:normal;">
<p align="center" style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html></string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QTextEdit" name="textEdit_3">
<property name="maximumSize">
<size>
<width>16777215</width>
<height>50</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">background-color: rgba(255, 255, 255, 0.1);</string>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="html">
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
p, li { white-space: pre-wrap; }
</style></head><body style=" font-family:'SimSun'; font-size:9pt; font-weight:400; font-style:normal;">
<p align="center" style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html></string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QTextEdit" name="textEdit_4">
<property name="maximumSize">
<size>
<width>16777215</width>
<height>50</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">background-color: rgba(255, 255, 255, 0.1);</string>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="html">
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
p, li { white-space: pre-wrap; }
</style></head><body style=" font-family:'SimSun'; font-size:9pt; font-weight:400; font-style:normal;">
<p align="center" style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html></string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QTextEdit" name="textEdit_5">
<property name="maximumSize">
<size>
<width>16777215</width>
<height>50</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">background-color: rgba(255, 255, 255, 0.1);</string>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="html">
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
p, li { white-space: pre-wrap; }
</style></head><body style=" font-family:'SimSun'; font-size:9pt; font-weight:400; font-style:normal;">
<p align="center" style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html></string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>685</width>
<height>23</height>
</rect>
</property>
<widget class="QMenu" name="menu">
<property name="title">
<string>文件</string>
</property>
</widget>
<addaction name="menu"/>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<resources>
<include location="putton.qrc"/>
</resources>
<connections/>
</ui>
(2)ui文件转化为py文件:Ui_music.py
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'f:\personaldata\Python资料\Python_studyltem\自制音乐播放器0103\UI_files\music.ui'
#
# Created by: PyQt5 UI code generator 5.15.9
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(685, 560)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(MainWindow.sizePolicy().hasHeightForWidth())
MainWindow.setSizePolicy(sizePolicy)
MainWindow.setMouseTracking(True)
MainWindow.setTabletTracking(True)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.formLayout = QtWidgets.QFormLayout(self.centralwidget)
self.formLayout.setObjectName("formLayout")
self.groupBox = QtWidgets.QGroupBox(self.centralwidget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.groupBox.sizePolicy().hasHeightForWidth())
self.groupBox.setSizePolicy(sizePolicy)
self.groupBox.setMaximumSize(QtCore.QSize(180, 16777215))
self.groupBox.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor))
self.groupBox.setMouseTracking(False)
self.groupBox.setLayoutDirection(QtCore.Qt.LeftToRight)
self.groupBox.setAutoFillBackground(False)
self.groupBox.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter)
self.groupBox.setCheckable(False)
self.groupBox.setObjectName("groupBox")
self.gridLayout_2 = QtWidgets.QGridLayout(self.groupBox)
self.gridLayout_2.setSizeConstraint(QtWidgets.QLayout.SetDefaultConstraint)
self.gridLayout_2.setObjectName("gridLayout_2")
self.pushButton = QtWidgets.QPushButton(self.groupBox)
self.pushButton.setMinimumSize(QtCore.QSize(0, 30))
self.pushButton.setCheckable(False)
self.pushButton.setChecked(False)
self.pushButton.setObjectName("pushButton")
self.gridLayout_2.addWidget(self.pushButton, 0, 1, 1, 1)
self.listWidget = QtWidgets.QListWidget(self.groupBox)
self.listWidget.setMinimumSize(QtCore.QSize(160, 0))
self.listWidget.setFrameShape(QtWidgets.QFrame.WinPanel)
self.listWidget.setFrameShadow(QtWidgets.QFrame.Raised)
self.listWidget.setObjectName("listWidget")
self.gridLayout_2.addWidget(self.listWidget, 2, 0, 1, 2)
self.device_ret = QtWidgets.QPushButton(self.groupBox)
self.device_ret.setMinimumSize(QtCore.QSize(0, 30))
self.device_ret.setObjectName("device_ret")
self.gridLayout_2.addWidget(self.device_ret, 0, 0, 1, 1)
self.formLayout.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.groupBox)
self.groupBox_2 = QtWidgets.QGroupBox(self.centralwidget)
self.groupBox_2.setObjectName("groupBox_2")
self.gridLayout_3 = QtWidgets.QGridLayout(self.groupBox_2)
self.gridLayout_3.setObjectName("gridLayout_3")
self.next_music = QtWidgets.QPushButton(self.groupBox_2)
self.next_music.setMinimumSize(QtCore.QSize(0, 30))
self.next_music.setMaximumSize(QtCore.QSize(40, 40))
self.next_music.setText("")
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap(":/put1/IMG/按钮/下首按钮.png"), QtGui.QIcon.Active, QtGui.QIcon.Off)
self.next_music.setIcon(icon)
self.next_music.setIconSize(QtCore.QSize(40, 40))
self.next_music.setObjectName("next_music")
self.gridLayout_3.addWidget(self.next_music, 3, 0, 1, 1)
self.last_music = QtWidgets.QPushButton(self.groupBox_2)
self.last_music.setMinimumSize(QtCore.QSize(0, 30))
self.last_music.setMaximumSize(QtCore.QSize(40, 40))
self.last_music.setBaseSize(QtCore.QSize(80, 80))
self.last_music.setStyleSheet("QPushButton {\"\n"
" \"background-color: green;\"\n"
" \"font: bold 20px;\" \n"
" \"border-width: 1px;\" \n"
" \"border-radius: 40px;\" \n"
" \"color: white;\" \n"
" }")
self.last_music.setText("")
icon1 = QtGui.QIcon()
icon1.addPixmap(QtGui.QPixmap(":/put1/IMG/按钮/上首按钮.png"), QtGui.QIcon.Active, QtGui.QIcon.Off)
self.last_music.setIcon(icon1)
self.last_music.setIconSize(QtCore.QSize(40, 40))
self.last_music.setObjectName("last_music")
self.gridLayout_3.addWidget(self.last_music, 3, 2, 1, 1)
self.jumpgif = QtWidgets.QLabel(self.groupBox_2)
self.jumpgif.setMinimumSize(QtCore.QSize(0, 40))
self.jumpgif.setMaximumSize(QtCore.QSize(16777215, 50))
self.jumpgif.setSizeIncrement(QtCore.QSize(0, 0))
self.jumpgif.setBaseSize(QtCore.QSize(0, 0))
self.jumpgif.setFrameShape(QtWidgets.QFrame.Panel)
self.jumpgif.setFrameShadow(QtWidgets.QFrame.Sunken)
self.jumpgif.setObjectName("jumpgif")
self.gridLayout_3.addWidget(self.jumpgif, 0, 0, 1, 10)
self.timeshow = QtWidgets.QLabel(self.groupBox_2)
self.timeshow.setMinimumSize(QtCore.QSize(55, 0))
self.timeshow.setMaximumSize(QtCore.QSize(60, 60))
self.timeshow.setObjectName("timeshow")
self.gridLayout_3.addWidget(self.timeshow, 2, 8, 1, 1)
self.play_stop_music = QtWidgets.QPushButton(self.groupBox_2)
self.play_stop_music.setMinimumSize(QtCore.QSize(0, 30))
self.play_stop_music.setMaximumSize(QtCore.QSize(40, 40))
self.play_stop_music.setStyleSheet("")
self.play_stop_music.setText("")
icon2 = QtGui.QIcon()
icon2.addPixmap(QtGui.QPixmap(":/put1/IMG/按钮/播放按钮.png"), QtGui.QIcon.Active, QtGui.QIcon.On)
self.play_stop_music.setIcon(icon2)
self.play_stop_music.setIconSize(QtCore.QSize(40, 40))
self.play_stop_music.setCheckable(False)
self.play_stop_music.setChecked(False)
self.play_stop_music.setAutoRepeat(False)
self.play_stop_music.setAutoExclusive(False)
self.play_stop_music.setObjectName("play_stop_music")
self.gridLayout_3.addWidget(self.play_stop_music, 3, 1, 1, 1)
self.horizontalSlider = QtWidgets.QSlider(self.groupBox_2)
self.horizontalSlider.setOrientation(QtCore.Qt.Horizontal)
self.horizontalSlider.setTickPosition(QtWidgets.QSlider.NoTicks)
self.horizontalSlider.setObjectName("horizontalSlider")
self.gridLayout_3.addWidget(self.horizontalSlider, 2, 0, 1, 8)
self.label_3 = QtWidgets.QLabel(self.groupBox_2)
self.label_3.setStyleSheet("image: url(:/put1/IMG/独家.png);")
self.label_3.setText("")
self.label_3.setObjectName("label_3")
self.gridLayout_3.addWidget(self.label_3, 2, 9, 2, 1)
self.soundvalue = QtWidgets.QLabel(self.groupBox_2)
self.soundvalue.setMaximumSize(QtCore.QSize(50, 50))
self.soundvalue.setObjectName("soundvalue")
self.gridLayout_3.addWidget(self.soundvalue, 3, 8, 1, 1)
self.verticalSlider = QtWidgets.QSlider(self.groupBox_2)
self.verticalSlider.setStyleSheet("")
self.verticalSlider.setMaximum(100)
self.verticalSlider.setOrientation(QtCore.Qt.Horizontal)
self.verticalSlider.setObjectName("verticalSlider")
self.gridLayout_3.addWidget(self.verticalSlider, 3, 6, 1, 2)
self.comboBox = QtWidgets.QComboBox(self.groupBox_2)
self.comboBox.setMinimumSize(QtCore.QSize(0, 40))
self.comboBox.setMaximumSize(QtCore.QSize(100, 16777215))
self.comboBox.setObjectName("comboBox")
icon3 = QtGui.QIcon()
icon3.addPixmap(QtGui.QPixmap(":/put1/IMG/next.png"), QtGui.QIcon.Active, QtGui.QIcon.On)
self.comboBox.addItem(icon3, "")
icon4 = QtGui.QIcon()
icon4.addPixmap(QtGui.QPixmap(":/put1/IMG/循环.jpg"), QtGui.QIcon.Active, QtGui.QIcon.On)
self.comboBox.addItem(icon4, "")
self.gridLayout_3.addWidget(self.comboBox, 3, 3, 1, 2)
self.showgdance0 = QtWidgets.QLabel(self.groupBox_2)
self.showgdance0.setMinimumSize(QtCore.QSize(132, 0))
self.showgdance0.setMaximumSize(QtCore.QSize(16777215, 16777215))
self.showgdance0.setStyleSheet("background-color: rgb(208, 208, 208);")
self.showgdance0.setFrameShape(QtWidgets.QFrame.WinPanel)
self.showgdance0.setFrameShadow(QtWidgets.QFrame.Raised)
self.showgdance0.setObjectName("showgdance0")
self.gridLayout_3.addWidget(self.showgdance0, 1, 0, 1, 3)
self.showgdance1 = QtWidgets.QLabel(self.groupBox_2)
self.showgdance1.setMinimumSize(QtCore.QSize(132, 0))
self.showgdance1.setMaximumSize(QtCore.QSize(16777215, 16777215))
self.showgdance1.setStyleSheet("background-color: rgb(208, 208, 208);")
self.showgdance1.setFrameShape(QtWidgets.QFrame.WinPanel)
self.showgdance1.setFrameShadow(QtWidgets.QFrame.Raised)
self.showgdance1.setObjectName("showgdance1")
self.gridLayout_3.addWidget(self.showgdance1, 1, 8, 1, 2)
self.label = QtWidgets.QLabel(self.groupBox_2)
self.label.setEnabled(True)
self.label.setFrameShape(QtWidgets.QFrame.Panel)
self.label.setFrameShadow(QtWidgets.QFrame.Sunken)
self.label.setObjectName("label")
self.gridLayout_3.addWidget(self.label, 3, 5, 1, 1)
self.scrollArea = QtWidgets.QScrollArea(self.groupBox_2)
self.scrollArea.setWidgetResizable(True)
self.scrollArea.setObjectName("scrollArea")
self.scrollAreaWidgetContents = QtWidgets.QWidget()
self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 183, 343))
self.scrollAreaWidgetContents.setObjectName("scrollAreaWidgetContents")
self.gridLayout = QtWidgets.QGridLayout(self.scrollAreaWidgetContents)
self.gridLayout.setObjectName("gridLayout")
self.textEdit = QtWidgets.QTextEdit(self.scrollAreaWidgetContents)
self.textEdit.setMaximumSize(QtCore.QSize(16777215, 50))
self.textEdit.setStyleSheet("background-color: rgba(255, 255, 255, 0.1);")
self.textEdit.setFrameShape(QtWidgets.QFrame.NoFrame)
self.textEdit.setObjectName("textEdit")
self.gridLayout.addWidget(self.textEdit, 0, 0, 1, 1)
self.textEdit_2 = QtWidgets.QTextEdit(self.scrollAreaWidgetContents)
self.textEdit_2.setMaximumSize(QtCore.QSize(16777215, 50))
self.textEdit_2.setStyleSheet("background-color: rgba(255, 255, 255, 0.1);")
self.textEdit_2.setFrameShape(QtWidgets.QFrame.NoFrame)
self.textEdit_2.setObjectName("textEdit_2")
self.gridLayout.addWidget(self.textEdit_2, 1, 0, 1, 1)
self.textEdit_3 = QtWidgets.QTextEdit(self.scrollAreaWidgetContents)
self.textEdit_3.setMaximumSize(QtCore.QSize(16777215, 50))
self.textEdit_3.setStyleSheet("background-color: rgba(255, 255, 255, 0.1);")
self.textEdit_3.setFrameShape(QtWidgets.QFrame.NoFrame)
self.textEdit_3.setObjectName("textEdit_3")
self.gridLayout.addWidget(self.textEdit_3, 2, 0, 1, 1)
self.textEdit_4 = QtWidgets.QTextEdit(self.scrollAreaWidgetContents)
self.textEdit_4.setMaximumSize(QtCore.QSize(16777215, 50))
self.textEdit_4.setStyleSheet("background-color: rgba(255, 255, 255, 0.1);")
self.textEdit_4.setFrameShape(QtWidgets.QFrame.NoFrame)
self.textEdit_4.setObjectName("textEdit_4")
self.gridLayout.addWidget(self.textEdit_4, 3, 0, 1, 1)
self.textEdit_5 = QtWidgets.QTextEdit(self.scrollAreaWidgetContents)
self.textEdit_5.setMaximumSize(QtCore.QSize(16777215, 50))
self.textEdit_5.setStyleSheet("background-color: rgba(255, 255, 255, 0.1);")
self.textEdit_5.setFrameShape(QtWidgets.QFrame.NoFrame)
self.textEdit_5.setObjectName("textEdit_5")
self.gridLayout.addWidget(self.textEdit_5, 4, 0, 1, 1)
self.scrollArea.setWidget(self.scrollAreaWidgetContents)
self.gridLayout_3.addWidget(self.scrollArea, 1, 3, 1, 5)
self.formLayout.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.groupBox_2)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 685, 23))
self.menubar.setObjectName("menubar")
self.menu = QtWidgets.QMenu(self.menubar)
self.menu.setObjectName("menu")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.menubar.addAction(self.menu.menuAction())
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.groupBox.setTitle(_translate("MainWindow", "曲目"))
self.pushButton.setText(_translate("MainWindow", "上级"))
self.device_ret.setText(_translate("MainWindow", "音频设备"))
self.groupBox_2.setTitle(_translate("MainWindow", "播放显示"))
self.jumpgif.setText(_translate("MainWindow", "<html><head/><body><p align=\"center\">展示GIF</p></body></html>"))
self.timeshow.setText(_translate("MainWindow", "<html><head/><body><p>0:0/0:0</p></body></html>"))
self.soundvalue.setText(_translate("MainWindow", "<html><head/><body><p>0</p></body></html>"))
self.comboBox.setItemText(0, _translate("MainWindow", "单曲循环"))
self.comboBox.setItemText(1, _translate("MainWindow", "列表循环"))
self.showgdance0.setText(_translate("MainWindow", "<html><head/><body><p align=\"center\">GIF跳动</p></body></html>"))
self.showgdance1.setText(_translate("MainWindow", "<html><head/><body><p align=\"center\">GIF跳动</p></body></html>"))
self.label.setText(_translate("MainWindow", "音量设置:"))
self.textEdit.setHtml(_translate("MainWindow", "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
"p, li { white-space: pre-wrap; }\n"
"</style></head><body style=\" font-family:\'SimSun\'; font-size:9pt; font-weight:400; font-style:normal;\">\n"
"<p align=\"center\" style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><br /></p></body></html>"))
self.textEdit_2.setHtml(_translate("MainWindow", "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
"p, li { white-space: pre-wrap; }\n"
"</style></head><body style=\" font-family:\'SimSun\'; font-size:9pt; font-weight:400; font-style:normal;\">\n"
"<p align=\"center\" style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><br /></p></body></html>"))
self.textEdit_3.setHtml(_translate("MainWindow", "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
"p, li { white-space: pre-wrap; }\n"
"</style></head><body style=\" font-family:\'SimSun\'; font-size:9pt; font-weight:400; font-style:normal;\">\n"
"<p align=\"center\" style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><br /></p></body></html>"))
self.textEdit_4.setHtml(_translate("MainWindow", "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
"p, li { white-space: pre-wrap; }\n"
"</style></head><body style=\" font-family:\'SimSun\'; font-size:9pt; font-weight:400; font-style:normal;\">\n"
"<p align=\"center\" style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><br /></p></body></html>"))
self.textEdit_5.setHtml(_translate("MainWindow", "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
"p, li { white-space: pre-wrap; }\n"
"</style></head><body style=\" font-family:\'SimSun\'; font-size:9pt; font-weight:400; font-style:normal;\">\n"
"<p align=\"center\" style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><br /></p></body></html>"))
self.menu.setTitle(_translate("MainWindow", "文件"))
from UI_files import putton_rc
三:界面设计完成,编写运行程序
(1)主程序文件:main.py
# -*- coding: UTF-8 -*-
import time
import os,logging
from UI_files.Ui_music import Ui_MainWindow
import sys
from PyQt5.QtGui import QIcon,QDesktopServices,QMovie # 用于添加图标
from PyQt5.QtWidgets import QMessageBox, QAction
from PyQt5.QtWidgets import QApplication,QMainWindow
from PyQt5.QtCore import pyqtSlot,QCoreApplication,QUrl,Qt
from ctypes import cast, POINTER
from comtypes import CLSCTX_ALL
from pycaw.pycaw import AudioUtilities, IAudioEndpointVolume
import traceback
from qtthread import RunThread
class Music_play(QMainWindow, Ui_MainWindow):
def __init__(self):
super().__init__() # 使用超类,继承父类的属性及方法
self.setupUi(self) # 构造窗体界面
self.setWindowIcon(QIcon("./IMG/icon/icon.jpg"))
self.setWindowTitle("自用音乐播放器V1.0 ") # 设置窗体主体
self.intUI()
# 初始化操作
def intUI(self):
self.my_logger = self.save_log()
self.piaymusicret = False
self.devices_ret = True
self.thread_1 = None
self.playmusic()
self.set_vo_init()
self.verticalSlider.valueChanged.connect(self.sl_value)
self.horizontalSlider.valueChanged.connect(self.set_music_current_time)
self.init_dongzuo()
self.init_dance()
self.create_folder()
self.get_musicfiles()
self.listWidget.itemDoubleClicked.connect(self.openmusicfiles) #绑定点击事件
self.menu_add()
# 添加打开本地文件夹按钮
def menu_add(self):
add_opeen= QAction("打开",self)
add_opeen.setShortcut('Ctrl+F')
add_opeen.triggered.connect(self.open_local_file)
self.menu.addAction(add_opeen)
add_opeens= QAction("重启工具",self)
add_opeens.setShortcut('Ctrl+S')
add_opeens.triggered.connect(self.restartApp)
self.menu.addAction(add_opeens)
self.textEdit.setDisabled(True)
self.textEdit_2.setDisabled(True)
self.textEdit_3.setDisabled(True)
self.textEdit_4.setDisabled(True)
self.textEdit_5.setDisabled(True)
# 打开本地文件夹
def open_local_file(self):
path = os.getcwd()
QDesktopServices.openUrl(QUrl.fromLocalFile(path))
# 重启软件
def restartApp(self):
python = sys.executable
os.execl(python, python, *sys.argv)
# 异常处理函数
def yichangchuli(func=None):
def deco(self,*args, **kwargs):
# print(func.__name__) #获取方法名称
try:
res = func(self,*args, **kwargs)
return res
except Exception as error:
error = traceback.format_exc()
print("错误异常:",error)
self.my_logger.debug(str(error))
if "_ctypes.COMError" in error:
self.close_button()
self.devices_ret = False
return deco
# 日志管理
def save_log(self):
# 1.创建一个logger(日志记录器)对象;
my_logger = logging.Logger("first_logger")
# 2.定义handler(日志处理器),决定把日志发到哪里;
my_handler = logging.FileHandler('日志.log',encoding='utf-8')
# 3.设置日志级别(level)和输出格式Formatters(日志格式器);
my_handler.setLevel(logging.DEBUG)
my_format = logging.Formatter("时间:%(asctime)s 函数名:%(funcName)s 日志信息:%(message)s 行号:%(lineno)d")
# 把handler添加到对应的logger中去。
my_handler.setFormatter(my_format)
my_logger.addHandler(my_handler)
# 使用:
my_logger.info("程序已启动...")
return my_logger
# 日志记录
def save_logshuju(self,value):
self.my_logger.debug(value)
def close_button(self):
self.play_stop_music.setEnabled(False)
self.next_music.setEnabled(False)
self.last_music.setEnabled(False)
self.device_ret.setStyleSheet("background-color: red")
self.device_ret.setText("音频打开失败")
# 横幅
def init_dongzuo(self):
path = "./IMG/横幅GIF1.gif"
movie = QMovie(path)
self.jumpgif.setMovie(movie)
self.jumpgif.setScaledContents(True)
movie.start()
# GFI 跳动1
def init_dance(self):
path = "./IMG/dance0.gif"
movie = QMovie(path)
self.showgdance0.setMovie(movie)
self.showgdance0.setScaledContents(True)
movie.start()
self.next_music.setEnabled(False)
self.last_music.setEnabled(False)
self.init_dances()
# GFI 跳动2
def init_dances(self):
path = "./IMG/dance0.gif"
movie = QMovie(path)
self.showgdance1.setMovie(movie)
self.showgdance1.setScaledContents(True)
movie.start()
# 如若没有,音乐文件自动创建
def create_folder(self):
paths = ["./音乐/音频文件","./音乐/歌词文件"]
for p in paths:
if os.path.isdir(p):
pass
else:
os.mkdir(p)
# 获取音频文件,并显示至界面
def get_musicfiles(self):
self.foder = None
self.listWidget.clear()
path = "./音乐"
musicfiles = os.listdir(path)
for file in musicfiles:
self.listWidget.addItem(file)
# 打开文件夹,列出音乐文件
def openmusicfiles(self):
# 判断是否为文件夹
selected_item = self.listWidget.currentItem()
item_text = selected_item.text()
music_name = ["mp3"]
try:
path = os.getcwd() + "/音乐/" + item_text
musicfiles = os.listdir(path)
except FileNotFoundError as error:
if self.devices_ret == False:
return
if self.thread_1 != None:
# 判断线程是否还在运行
if self.thread_1.isRunning():
print("线程正在运行")
self.thread_1.set_ret()
self.thread_1.quit()
time.sleep(0.3)
paths = self.foder +"/{}".format(item_text)
self.thread_1 = RunThread(parent="music_bofang",msg=[paths])
self.thread_1.trigger.connect(self.send_information)
self.thread_1.start()
self.playmusic()
self.groupBox_2.setTitle("播放显示:{}".format(item_text))
return item_text
self.listWidget.clear()
for file in musicfiles:
for name in music_name:
self.foder = path
if name in file:
self.listWidget.addItem(file)
if self.groupBox_2.title() == "播放显示":
# 设置第当前选择的项0
current_item = self.listWidget.item(0)
self.listWidget.setCurrentItem(current_item)
else:
shuju = str(self.groupBox_2.title()).split(":")
for i in range(self.listWidget.count()):
item = self.listWidget.item(i)
text = item.text()
if text == shuju[1]:
current_item = self.listWidget.item(i)
self.listWidget.setCurrentItem(current_item)
@pyqtSlot()
def on_pushButton_clicked(self):
if self.thread_1 != None:
# 判断线程是否还在运行
if self.thread_1.isRunning():
print("线程正在运行")
# 后两项分别为按钮(以|隔开,共有7种按钮类型,见示例后)、默认按钮(省略则默认为第一个按钮)
reply = QMessageBox.question(self, "音乐", "是否停止播放音乐,返回上级目录?", QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
if reply == 16384:
self.thread_1.set_ret()
self.thread_1.quit()
time.sleep(0.5)
self.get_musicfiles()
self.thread_1 = None
else:
self.get_musicfiles()
# 获取当前电脑的音量值,并设置
@yichangchuli
def set_vo_init(self):
self.play_stop_music.setEnabled(False)
# 获取自己的音频设备及其参数
devices = AudioUtilities.GetSpeakers()
interface = devices.Activate(IAudioEndpointVolume._iid_, CLSCTX_ALL, None)
volume = cast(interface, POINTER(IAudioEndpointVolume))
# 获取音量范围,我的电脑经测试是(-65.25, 0.0, 0.03125),第一个代表最小值,第二个代表最大值,第三个是增量。
vol_range = volume.GetVolumeRange()
print(vol_range)
# 获取当前的音量值
vol_now = volume.GetMasterVolumeLevel()
print("获取音量数值:",int(vol_now))
value = self.vol_tansfer(x=int(vol_now),chang="get")
_translate = QCoreApplication.translate
self.soundvalue.setText(_translate("MainWindow", "<html><head/><body><p align=\"center\">{}</p></body></html>".format(value)))
self.verticalSlider.setValue(value)
self.device_ret.setStyleSheet("background-color: green")
self.device_ret.setText("音频打开成功")
self.devices_ret = True
# 播放音乐
def playmusic(self):
self.piaymusicret = True
self.play_stop_music.setIcon(QIcon('./IMG/按钮/播放按钮1.png'))
@pyqtSlot()
def on_device_ret_clicked(self):
if self.device_ret.text() == "音频打开失败":
self.set_vo_init()
# 播放暂停按钮
@pyqtSlot()
def on_play_stop_music_clicked(self):
if self.piaymusicret == True:
self.play_stop_music.setIcon(QIcon('./IMG/按钮/暂停按钮.png'))
self.piaymusicret = None
self.thread_1.music_stop()
elif self.piaymusicret == None:
self.play_stop_music.setIcon(QIcon('./IMG/按钮/播放按钮1.png'))
self.piaymusicret = True
self.thread_1.music_bofangs()
# 设置音量
def sl_value(self):
_translate = QCoreApplication.translate
value = self.verticalSlider.value()
self.soundvalue.setText(_translate("MainWindow", "<html><head/><body><p align=\"center\">{}</p></body></html>".format(value)))
self.set_volume(value)
# 设置音乐时间
def set_music_current_time(self):
pass
@pyqtSlot()
def on_last_music_pressed(self):
self.last_music.setIcon(QIcon('./IMG/按钮/上首按钮1.png'))
# 切换上一首歌
@pyqtSlot()
def on_last_music_released(self):
self.last_music.setIcon(QIcon('./IMG/按钮/上首按钮.png'))
# 获取所有数据的数量
all_suoyin = self.listWidget.count()
print(all_suoyin)
# 获取当前选中的所有项
selected_items = self.listWidget.selectedItems()
# 获取当前选中项的索引
selected_indexes = [self.listWidget.row(item) for item in selected_items]
print(selected_indexes[0]) # 输出选中项的索引
if selected_indexes[0]-1 >= 0:
# 设置第当前选择的项
current_item = self.listWidget.item(selected_indexes[0]-1)
self.listWidget.setCurrentItem(current_item)
# 设置选中项的背景样式
self.listWidget.setStyleSheet("QListWidget::item:selected { background-color: rgb(0, 255, 127); }")
# 判断线程是否还在运行
if self.thread_1.isRunning():
print("线程正在运行")
self.thread_1.set_ret()
self.thread_1.quit()
else:
print("线程已停止")
self.openmusicfiles()
@pyqtSlot()
def on_next_music_pressed(self):
self.next_music.setIcon(QIcon('./IMG/按钮/下首按钮1.png'))
# 切换下一首歌
@pyqtSlot()
def on_next_music_released(self):
self.next_music.setEnabled(False)
self.next_music.setIcon(QIcon('./IMG/按钮/下首按钮.png'))
# 获取所有数据的数量
all_suoyin = self.listWidget.count()
print(all_suoyin)
# 获取当前选中的所有项
selected_items = self.listWidget.selectedItems()
# 获取当前选中项的索引
selected_indexes = [self.listWidget.row(item) for item in selected_items]
print(selected_indexes[0]) # 输出选中项的索引
if selected_indexes[0]+1 <= all_suoyin-1:
# 设置第当前选择的项
current_item = self.listWidget.item(selected_indexes[0]+1)
self.listWidget.setCurrentItem(current_item)
# 设置选中项的背景样式
self.listWidget.setStyleSheet("QListWidget::item:selected { background-color: rgb(0, 82, 245); }")
# 判断线程是否还在运行
if self.thread_1.isRunning():
print("线程正在运行")
self.thread_1.set_ret()
self.thread_1.quit()
else:
print("线程已停止")
time.sleep(0.2)
self.openmusicfiles()
# 列表循环切歌
@pyqtSlot()
def listcutmusic(self):
self.next_music.setIcon(QIcon('./IMG/按钮/下首按钮.png'))
# 获取所有数据的数量
all_suoyin = self.listWidget.count()
print("所有数量:",all_suoyin)
# 获取当前选中的所有项
selected_items = self.listWidget.selectedItems()
# 获取当前选中项的索引
selected_indexes = [self.listWidget.row(item) for item in selected_items]
print(selected_indexes[0]) # 输出选中项的索引
if selected_indexes[0]+1 <= all_suoyin-1:
# 设置第当前选择的项
current_item = self.listWidget.item(selected_indexes[0]+1)
self.listWidget.setCurrentItem(current_item)
# 设置选中项的背景样式
self.listWidget.setStyleSheet("QListWidget::item:selected { background-color: rgb(0, 82, 245); }")
text = self.openmusicfiles()
elif selected_indexes[0]+1 > all_suoyin-1:
# 设置第当前选择的项
current_item = self.listWidget.item(0)
self.listWidget.setCurrentItem(current_item)
# 设置选中项的背景样式
self.listWidget.setStyleSheet("QListWidget::item:selected { background-color: rgb(0, 82, 245); }")
text = self.openmusicfiles()
return text
# 设置音量值
@yichangchuli
def set_volume(self,volume=None):
# 调用Windows API函数
# 获取自己的音频设备及其参数
devices = AudioUtilities.GetSpeakers()
interface = devices.Activate(IAudioEndpointVolume._iid_, CLSCTX_ALL, None)
volumes = cast(interface, POINTER(IAudioEndpointVolume))
#设置声音大小
volumes.SetMasterVolumeLevel(self.vol_tansfer(volume), None)
# 音量值转换
def vol_tansfer(self,x,chang=None):
dicts = {0: -63.05, 1: -56.99, 2: -51.67, 3: -47.74, 4: -44.62, 5: -41.03, 6: -39.82, 7: -37.89, 8: -36.17,
9: -34.63, 10: -33.24,
11: -31.96, 12: -30.78, 13: -29.68, 14: -28.66, 15: -27.7, 16: -26.8, 17: -25.95, 18: -25.15, 19: -24.38,
20: -23.65,
21: -22.96, 22: -22.3, 23: -21.66, 24: -21.05, 25: -20.46, 26: -19.9, 27: -19.35, 28: -18.82, 29: -18.32,
30: -17.82,
31: -17.35, 32: -16.88, 33: -16.44, 34: -16.0, 35: -15.58, 36: -15.16, 37: -14.76, 38: -14.37, 39: -13.99,
40: -13.62,
41: -13.26, 42: -12.9, 43: -12.56, 44: -12.22, 45: -11.89, 46: -11.56, 47: -11.24, 48: -10.93, 49: -10.63,
50: -10.33,
51: -10.04, 52: -9.75, 53: -9.47, 54: -9.19, 55: -8.92, 56: -8.65, 57: -8.39, 58: -8.13, 59: -7.88,
60: -7.63,
61: -7.38, 62: -7.14, 63: -6.9, 64: -6.67, 65: -6.44, 66: -6.21, 67: -5.99, 68: -5.76, 69: -5.55, 70: -5.33,
71: -5.12, 72: -4.91, 73: -4.71, 74: -4.5, 75: -4.3, 76: -4.11, 77: -3.91, 78: -3.72, 79: -3.53, 80: -3.34,
81: -3.15, 82: -2.97, 83: -2.79, 84: -2.61, 85: -2.43, 86: -2.26, 87: -2.09, 88: -1.91, 89: -1.75,
90: -1.58,
91: -1.41, 92: -1.25, 93: -1.09, 94: -0.93, 95: -0.77, 96: -0.61, 97: -0.46, 98: -0.3, 99: -0.15, 100: 0.0}
if chang == None:
return dicts[x]
elif chang == "get":
for value,shuju in dicts.items():
if str(x) in str(shuju):
print(value)
return value
def get_time(self):
shijian = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())
return shijian
# 接收信息
def send_information(self,text=[]):
#接收信息
time_now = self.get_time()
if text[0] == "musicplay_end":
if self.comboBox.currentText() == "单曲循环":
if self.piaymusicret == True:
item_text = self.openmusicfiles()
self.my_logger.info("单曲循环:"+ item_text)
elif self.comboBox.currentText() == "列表循环":
text = self.listcutmusic()
self.my_logger.info("当前播放歌曲:"+ text)
elif text[0] == "error_save":
self.my_logger.debug(text[1])
elif text[0] == "music_time":
self.timeshow.setText(text[1])
elif text[0] == "musicplay_time":
# 设置音乐时长大小
self.horizontalSlider.setMaximum(int(text[1])) # 设置最大值为10
elif text[0] == "music_time_slider":
self.horizontalSlider.setValue(int(text[1]))
elif text[0] == "pustton_huifu":
self.play_stop_music.setEnabled(True)
self.next_music.setEnabled(True)
self.last_music.setEnabled(True)
elif text[0] == "show_gechi":
if text[1][0] == 0:
self.textEdit.setText(text[1][1])
self.textEdit.setAlignment(Qt.AlignCenter) # 设置文本居中对齐
elif text[1][0] == 1:
self.textEdit_2.setText(text[1][1])
self.textEdit_2.setAlignment(Qt.AlignCenter) # 设置文本居中对齐
elif text[1][0] == 2:
self.textEdit_3.setText(text[1][1])
self.textEdit_3.setAlignment(Qt.AlignCenter) # 设置文本居中对齐
elif text[1][0] == 3:
self.textEdit_4.setText(text[1][1])
self.textEdit_4.setAlignment(Qt.AlignCenter) # 设置文本居中对齐
elif text[1][0] == 4:
self.textEdit_5.setText('<font color=\"#0000FF\">{}</font>'.format(text[1][1]))
self.textEdit_5.setAlignment(Qt.AlignCenter) # 设置文本居中对齐
elif text[0] == "nomusicfile":
self.textEdit.setText(text[1])
self.textEdit.setAlignment(Qt.AlignCenter) # 设置文本居中对齐
elif text[0] == "clear_musicfile":
self.textEdit.setText("")
self.textEdit_2.setText("")
self.textEdit_3.setText("")
self.textEdit_4.setText("")
self.textEdit_5.setText("")
def closeEvent(self, event):
"""
重写closeEvent方法,实现dialog窗体关闭时执行一些代码
:param event: close()触发的事件
:return: None
"""
reply = QMessageBox.question(self,
'本程序',
"是否要退出程序?",
QMessageBox.Yes | QMessageBox.No,
QMessageBox.Yes)
if reply == QMessageBox.Yes:
if self.thread_1 != None:
# 判断线程是否还在运行
if self.thread_1.isRunning():
print("线程正在运行")
self.thread_1.set_ret()
self.thread_1.quit()
self.thread_1.wait()
else:
print("线程已停止")
event.accept()
else:
event.ignore()
if __name__ == "__main__":
app = QApplication(sys.argv)
# 设置应用程序的风格
app.setStyle('Fusion')
w = Music_play()
w.show()
sys.exit(app.exec_())
(2)业务逻辑程序文件(处理耗时过长的程序):qtthread.py
from PyQt5.QtCore import pyqtSignal,QThread
import traceback
import os
import time
from pygame import mixer
from mutagen.mp3 import MP3
#业务线程
class RunThread(QThread):
# 通过类成员对象定义信号对象
# _signal = pyqtSignal(str)
trigger = pyqtSignal(list)
def __init__(self, parent=None,msg=None):
super(RunThread, self).__init__()
self.parent = parent
self.msg = msg
# def __del__(self): #等待
# self.wait()
# 异常处理函数
def yichangchuli(func=None):
def deco(self,*args, **kwargs):
# print(func.__name__) #获取方法名称
try:
res = func(self,*args, **kwargs)
return res
except Exception as error:
error = traceback.format_exc()
print("错误异常:",error)
self.send_emit(change="error_save",result="{}".format(error))
return deco
'''处理业务逻辑'''
@yichangchuli
def run(self):
#识别业务命令,在进行执行
if self.parent == "music_bofang":
self.save_gechi = []
self.music_bofang()
def music_bofang(self):
paths = self.msg[0]
print(paths)
self.mixer = mixer
self.mixer.init()
self.mixer.music.load(paths)
# 获取音频时长
audio = MP3(paths)
duration = audio.info.length
# 输出音乐时长
print("音乐时长:", duration)
self.send_times(du=int(duration))
shijian = self.jisuan_time(du=duration)
# 设置音乐播放完成事件
self.mixer.music.set_endevent()
self.mixer.music.play()
self.send_emit(change="pustton_huifu",result="true")
time.sleep(0.5)
self.pos_get(du=shijian)
# self.jianting()
def pos_get(self,du):
# 处理歌词和时间
liebiaotime = self.count_func()
if liebiaotime != None:
self.gechi = liebiaotime[1]
print("歌词:",liebiaotime[1])
# 清除显示的文件
self.send_emit(change="clear_musicfile",result="")
else:
self.send_emit(change="clear_musicfile",result="")
self.send_emit(change="nomusicfile",result="无对应歌词文件")
shuju = str(du).split(":")
shuju = int(shuju[0])*60+ int(shuju[1])
print("总时间:",shuju)
self.ret = True
while self.ret:
time.sleep(1)
if self.ret == False:
print("线程结束!")
self.mixer.music.stop()
self.mixer.stop()
break
pos = self.mixer.music.get_pos()
print("位置:",int(pos/1000))
weizhi = int(pos/1000)
if 0 < int(pos/1000) < 60:
self.send_emit(change="music_time",result="{}-{}".format(int(pos/1000),du))
self.send_emit(change="music_time_slider",result="{}".format(int(pos/1000)))
if liebiaotime != None:
self.show_music_gechi(liebiao=liebiaotime,weizhi=weizhi)
elif 60 <= int(pos/1000) < shuju:
self.send_emit(change="music_time_slider",result="{}".format(int(pos/1000)))
shujus = self.jisuan_time(du=int(pos/1000))
self.send_emit(change="music_time",result="{}-{}".format(shujus,du))
if liebiaotime != None:
self.show_music_gechi(liebiao=liebiaotime,weizhi=weizhi)
elif weizhi >= shuju or weizhi == 0:
print("播放结束!")
self.ret = False
self.mixer.stop()
self.send_emit(change="musicplay_end",result="播放结束")
# 对应时间的对应歌词显示
def show_music_gechi(self,liebiao,weizhi):
weizhi = self.chuli_weizhi(weizhi)
index = liebiao[0].index(str(weizhi)) if (str(weizhi) in liebiao[0]) else -1 # 有则返回下标,没有返回-1
# print('列表中元素"{}"的下标为:'.format(weizhi), index)
if index != -1:
self.send_gechi(index)
# 处理歌词的时间
def chuli_weizhi(self,shuju):
if 0 < shuju < 10:
shuju = "00:0{}".format(shuju)
elif 10 <= shuju < 60:
shuju = "00:{}".format(shuju)
elif 60 <= shuju < 70:
shujus = self.jisuan_time(shuju)
shujus = shujus.split(":")
shujus = shujus[0]+":0" +shujus[1]
shuju = "0{}".format(shujus)
# print("=====",shuju)
elif 70 <= shuju:
shujus = self.jisuan_time(shuju)
shuju = "0{}".format(shujus)
return shuju
def send_gechi(self,index):
shuju = self.gechi[index]
# print("打印歌词:",shuju)
# 保存歌词的列表,数目只能保持在5个
self.save_gechi.append(shuju)
if len(self.save_gechi) <= 5:
i=0
for gechi_shuju in self.save_gechi:
self.send_emits(change="show_gechi",result=[i,gechi_shuju])
i= i+1
else:
self.save_gechi.pop(0)
i=0
for gechi_shuju in self.save_gechi:
self.send_emits(change="show_gechi",result=[i,gechi_shuju])
i= i+1
# 处理歌词和时间
def count_func(self):
filepath = str(self.msg[0]).replace("音频文件","歌词文件")
filepath = filepath.split(".")
filepath = filepath[0] + ".txt"
print("歌词文件路径:",filepath)
# 判断歌词文件是否存在
if os.path.exists(filepath):
#filepath = "F:/personaldata/Python资料/Python_studyltem/自制音乐播放器0103/音乐/歌词文件/姑娘别哭泣.txt"
with open(filepath, 'r',encoding="gbk") as f:
self.data = f.readlines()
# print(self.data)
# 歌词数据处理 分开时间和歌词,一一对应,列表保存数据
liebiao1 = []
liebiao2 = []
for shuju in self.data:
timesave0 = shuju.split("]")
timesave1 = timesave0[0].replace("[","")
# print(timesave1)
timesave2 = timesave1.split(".")
timesave3 = timesave2[0]
# print(timesave3)
# 保存时间
liebiao1.append(timesave3)
# 保存歌词
liebiao2.append(timesave0[1])
print("歌词时间:",liebiao1)
return [liebiao1,liebiao2]
else:
self.send_emit(change="error_save",result="无歌词文件:".format(filepath))
return None
def jianting(self):
# 监听事件
while True:
ret = self.mixer.music.get_busy()
if ret == True:
continue
elif ret == False:
print('音乐播放完成')
self.mixer.music.stop()
self.send_emit(change="musicplay_end",result="播放结束")
break
else:
shuju = self.mixer.music.get_endevent()
print("异常错误:",shuju)
# 计算音频时长
def jisuan_time(self,du):
y = 0
for i in range(1,5):
y = int(du) - i*60
if 0 <= y < 60:
shijian = str(i) +":"+"{}".format(y)
print("转化时间:",shijian)
return shijian
# 将计算的时间,传给主界面
def send_times(self,du):
self.send_emit(change="musicplay_time",result="{}".format(du))
# 停止获取音频位置数据
def set_ret(self):
self.ret = False
# 音乐停止
def music_stop(self):
self.mixer.music.pause()
# 音乐停止
def music_bofangs(self):
self.mixer.music.unpause()
def send_emit(self,change="info",result=""):
self.trigger.emit([change, result])
def send_emits(self,change="info",result=[]):
self.trigger.emit([change, result])