感受一下Pyqt5的水平布局与垂直布局及其交叉展示
需求:
- 4个按钮水平排放
- 4个按钮垂直排放
- 水平排放与垂直排放并用
- 实战:音乐播放器UI
水平排放
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QHBoxLayout
class MyWindow(QWidget):
def __init__(self):
super().__init__()
# 设置窗口标题
self.setWindowTitle("mdwsw")
# 创建一个水平布局
layout = QHBoxLayout()
# 创建4个按钮
button1 = QPushButton("Button 1")
button2 = QPushButton("Button 2")
button3 = QPushButton("Button 3")
button4 = QPushButton("Button 4")
# 将按钮添加到布局中
layout.addWidget(button1)
layout.addWidget(button2)
layout.addWidget(button3)
layout.addWidget(button4)
# 设置窗口的布局
self.setLayout(layout)
# 设置窗口大小
self.setGeometry(100, 100, 400, 100)
# 主程序
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MyWindow()
window.show()
sys.exit(app.exec_())
效果展示
垂直排放
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QHBoxLayout, QVBoxLayout
class MyWindow(QWidget):
def __init__(self):
super().__init__()
# 设置窗口标题
self.setWindowTitle("mdwsw")
# 创建一个水平布局
layout = QVBoxLayout()
# 创建4个按钮
button1 = QPushButton("Button 1")
button2 = QPushButton("Button 2")
button3 = QPushButton("Button 3")
button4 = QPushButton("Button 4")
# 将按钮添加到布局中
layout.addWidget(button1)
layout.addWidget(button2)
layout.addWidget(button3)
layout.addWidget(button4)
# 设置窗口的布局
self.setLayout(layout)
# 设置窗口大小
self.setGeometry(100, 100, 400, 100)
# 主程序
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MyWindow()
window.show()
sys.exit(app.exec_())
效果展示
交叉展示
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QHBoxLayout, QVBoxLayout
class MyWindow(QWidget):
def __init__(self):
super().__init__()
# 设置窗口标题
self.setWindowTitle("mdwsw")
# 创建一个垂直布局
layout_v = QVBoxLayout()
# 创建一个水平布局
layout_h = QHBoxLayout()
# 创建4个按钮
button1 = QPushButton("Button 1")
button2 = QPushButton("Button 2")
button3 = QPushButton("Button 3")
button4 = QPushButton("Button 4")
# 将按钮添加到布局中
layout_h.addWidget(button1)
layout_h.addWidget(button2)
layout_h.addWidget(button3)
layout_h.addWidget(button4)
# 将水平布局添加到垂直布局中
layout_v.addLayout(layout_h)
# 创建4个按钮
button5 = QPushButton("Button 5")
button6 = QPushButton("Button 6")
button7 = QPushButton("Button 7")
button8 = QPushButton("Button 8")
layout_v.addWidget(button5)
layout_v.addWidget(button6)
layout_v.addWidget(button7)
layout_v.addWidget(button8)
# 设置窗口的布局
self.setLayout(layout_v)
# 设置窗口大小
self.setGeometry(100, 100, 400, 200)
# 主程序
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MyWindow()
window.show()
sys.exit(app.exec_())
效果展示
实战
结合上面的知识,制作一个音乐播放器UI
import sys
from PyQt5.QtWidgets import (
QApplication, QWidget, QPushButton, QHBoxLayout, QVBoxLayout, QSlider, QLabel
)
from PyQt5.QtCore import Qt
class MusicPlayer(QWidget):
def __init__(self):
super().__init__()
# 设置窗口标题
self.setWindowTitle("Music Player_Mdwsw")
# 创建主布局
main_layout = QVBoxLayout()
# 歌曲信息
self.song_info = QLabel("当前播放: 未知 - 未知")
self.song_info.setAlignment(Qt.AlignCenter)
main_layout.addWidget(self.song_info)
# 进度条
self.progress_slider = QSlider(Qt.Horizontal)
self.progress_slider.setRange(0, 100) # 假设歌曲长度为 100
self.progress_slider.setValue(0) # 初始进度为 0
main_layout.addWidget(self.progress_slider)
# 控制按钮布局
control_layout = QHBoxLayout()
# 上一首按钮
self.prev_button = QPushButton("上一首")
control_layout.addWidget(self.prev_button)
# 播放/暂停按钮
self.play_pause_button = QPushButton("播放")
control_layout.addWidget(self.play_pause_button)
# 停止按钮
self.stop_button = QPushButton("停止")
control_layout.addWidget(self.stop_button)
# 下一首按钮
self.next_button = QPushButton("下一首")
control_layout.addWidget(self.next_button)
# 将控制按钮布局添加到主布局
main_layout.addLayout(control_layout)
# 音量控制布局
volume_layout = QHBoxLayout()
# 音量标签
volume_label = QLabel("音量:")
volume_layout.addWidget(volume_label)
# 音量滑块
self.volume_slider = QSlider(Qt.Horizontal)
self.volume_slider.setRange(0, 100)
self.volume_slider.setValue(50) # 初始音量为 50
volume_layout.addWidget(self.volume_slider)
# 将音量控制布局添加到主布局
main_layout.addLayout(volume_layout)
# 设置主布局
self.setLayout(main_layout)
# 设置窗口大小
self.setGeometry(100, 100, 400, 200)
# 连接按钮信号和槽函数
self.play_pause_button.clicked.connect(self.toggle_play_pause)
self.stop_button.clicked.connect(self.stop_music)
self.prev_button.clicked.connect(self.prev_song)
self.next_button.clicked.connect(self.next_song)
self.volume_slider.valueChanged.connect(self.adjust_volume)
self.progress_slider.valueChanged.connect(self.seek_position)
# 槽函数
def toggle_play_pause(self):
if self.play_pause_button.text() == "播放":
self.play_pause_button.setText("暂停")
print("播放音乐")
else:
self.play_pause_button.setText("播放")
print("暂停音乐")
def stop_music(self):
self.play_pause_button.setText("播放")
print("停止播放")
def prev_song(self):
print("切换到上一首")
def next_song(self):
print("切换到下一首")
def adjust_volume(self, value):
print(f"调整音量: {value}")
def seek_position(self, value):
print(f"跳转到进度: {value}%")
# 主程序
if __name__ == "__main__":
app = QApplication(sys.argv)
player = MusicPlayer()
player.show()
sys.exit(app.exec_())
效果展示
点击触发后日志展示:
跳转到进度: 40%
切换到上一首
播放音乐
停止播放
切换到下一首
跳转到进度: 41%
调整音量: 56
定制一个属于自己的音乐播放器
选择音频文件播放
import sys
from PyQt5.QtWidgets import (
QApplication, QWidget, QPushButton, QHBoxLayout, QVBoxLayout, QSlider, QLabel, QFileDialog
)
from PyQt5.QtCore import Qt, QUrl, QTimer
from PyQt5.QtMultimedia import QMediaPlayer, QMediaContent
from PyQt5.QtMultimediaWidgets import QVideoWidget
class MusicPlayer(QWidget):
def __init__(self):
super().__init__()
# 初始化媒体播放器
self.media_player = QMediaPlayer()
self.playlist = [] # 播放列表
self.current_index = 0 # 当前播放的歌曲索引
# 设置窗口标题
self.setWindowTitle("本地音乐播放器")
# 创建主布局
main_layout = QVBoxLayout()
# 歌曲信息
self.song_info = QLabel("当前播放: 无")
self.song_info.setAlignment(Qt.AlignCenter)
main_layout.addWidget(self.song_info)
# 进度条
self.progress_slider = QSlider(Qt.Horizontal)
self.progress_slider.setRange(0, 100)
self.progress_slider.setValue(0)
self.progress_slider.sliderMoved.connect(self.seek_position)
main_layout.addWidget(self.progress_slider)
# 控制按钮布局
control_layout = QHBoxLayout()
# 上一首按钮
self.prev_button = QPushButton("上一首")
self.prev_button.clicked.connect(self.prev_song)
control_layout.addWidget(self.prev_button)
# 播放/暂停按钮
self.play_pause_button = QPushButton("播放")
self.play_pause_button.clicked.connect(self.toggle_play_pause)
control_layout.addWidget(self.play_pause_button)
# 停止按钮
self.stop_button = QPushButton("停止")
self.stop_button.clicked.connect(self.stop_music)
control_layout.addWidget(self.stop_button)
# 下一首按钮
self.next_button = QPushButton("下一首")
self.next_button.clicked.connect(self.next_song)
control_layout.addWidget(self.next_button)
# 将控制按钮布局添加到主布局
main_layout.addLayout(control_layout)
# 音量控制布局
volume_layout = QHBoxLayout()
# 音量标签
volume_label = QLabel("音量:")
volume_layout.addWidget(volume_label)
# 音量滑块
self.volume_slider = QSlider(Qt.Horizontal)
self.volume_slider.setRange(0, 100)
self.volume_slider.setValue(50)
self.volume_slider.valueChanged.connect(self.adjust_volume)
volume_layout.addWidget(self.volume_slider)
# 将音量控制布局添加到主布局
main_layout.addLayout(volume_layout)
# 添加文件选择按钮
self.file_button = QPushButton("选择音乐文件")
self.file_button.clicked.connect(self.open_file_dialog)
main_layout.addWidget(self.file_button)
# 设置主布局
self.setLayout(main_layout)
# 设置窗口大小
self.setGeometry(100, 100, 400, 200)
# 定时器用于更新进度条
self.timer = QTimer()
self.timer.timeout.connect(self.update_progress)
# 打开文件对话框
def open_file_dialog(self):
file_dialog = QFileDialog()
file_dialog.setFileMode(QFileDialog.ExistingFiles)
file_dialog.setNameFilter("音乐文件 (*.mp3 *.wav)")
if file_dialog.exec_():
files = file_dialog.selectedFiles()
self.playlist = files
self.current_index = 0
self.load_song(self.current_index)
# 加载歌曲
def load_song(self, index):
if 0 <= index < len(self.playlist):
song_path = self.playlist[index]
self.media_player.setMedia(QMediaContent(QUrl.fromLocalFile(song_path)))
self.song_info.setText(f"当前播放: {song_path.split('/')[-1]}")
self.play_pause_button.setText("播放")
self.media_player.play()
# 切换播放/暂停
def toggle_play_pause(self):
if self.media_player.state() == QMediaPlayer.PlayingState:
self.media_player.pause()
self.play_pause_button.setText("播放")
else:
self.media_player.play()
self.play_pause_button.setText("暂停")
# 停止播放
def stop_music(self):
self.media_player.stop()
self.play_pause_button.setText("播放")
# 上一首
def prev_song(self):
if self.current_index > 0:
self.current_index -= 1
self.load_song(self.current_index)
# 下一首
def next_song(self):
if self.current_index < len(self.playlist) - 1:
self.current_index += 1
self.load_song(self.current_index)
# 调整音量
def adjust_volume(self, value):
self.media_player.setVolume(value)
# 跳转到指定位置
def seek_position(self, value):
if self.media_player.duration() > 0:
position = int((value / 100) * self.media_player.duration())
self.media_player.setPosition(position)
# 更新进度条
def update_progress(self):
if self.media_player.duration() > 0:
progress = int((self.media_player.position() / self.media_player.duration()) * 100)
self.progress_slider.setValue(progress)
# 播放状态改变时启动或停止定时器
def media_state_changed(self, state):
if state == QMediaPlayer.PlayingState:
self.timer.start(1000) # 每秒更新一次进度条
else:
self.timer.stop()
# 初始化媒体播放器信号连接
def init_media_player(self):
self.media_player.stateChanged.connect(self.media_state_changed)
# 主程序
if __name__ == "__main__":
app = QApplication(sys.argv)
player = MusicPlayer()
player.init_media_player() # 初始化媒体播放器信号连接
player.show()
sys.exit(app.exec_())
效果展示
优化:选择文件夹,识别文件夹内音频文件,播放音频
import sys
import os
from PyQt5.QtWidgets import (
QApplication, QWidget, QPushButton, QHBoxLayout, QVBoxLayout, QSlider, QLabel, QFileDialog
)
from PyQt5.QtCore import Qt, QUrl, QTimer
from PyQt5.QtMultimedia import QMediaPlayer, QMediaContent
class MusicPlayer(QWidget):
def __init__(self):
super().__init__()
# 初始化媒体播放器
self.media_player = QMediaPlayer()
self.playlist = [] # 播放列表
self.current_index = 0 # 当前播放的歌曲索引
# 设置窗口标题
self.setWindowTitle("本地音乐播放器")
# 创建主布局
main_layout = QVBoxLayout()
# 歌曲信息
self.song_info = QLabel("当前播放: 无")
self.song_info.setAlignment(Qt.AlignCenter)
main_layout.addWidget(self.song_info)
# 进度条
self.progress_slider = QSlider(Qt.Horizontal)
self.progress_slider.setRange(0, 100)
self.progress_slider.setValue(0)
self.progress_slider.sliderMoved.connect(self.seek_position)
main_layout.addWidget(self.progress_slider)
# 控制按钮布局
control_layout = QHBoxLayout()
# 上一首按钮
self.prev_button = QPushButton("上一首")
self.prev_button.clicked.connect(self.prev_song)
control_layout.addWidget(self.prev_button)
# 播放/暂停按钮
self.play_pause_button = QPushButton("播放")
self.play_pause_button.clicked.connect(self.toggle_play_pause)
control_layout.addWidget(self.play_pause_button)
# 停止按钮
self.stop_button = QPushButton("停止")
self.stop_button.clicked.connect(self.stop_music)
control_layout.addWidget(self.stop_button)
# 下一首按钮
self.next_button = QPushButton("下一首")
self.next_button.clicked.connect(self.next_song)
control_layout.addWidget(self.next_button)
# 将控制按钮布局添加到主布局
main_layout.addLayout(control_layout)
# 音量控制布局
volume_layout = QHBoxLayout()
# 音量标签
volume_label = QLabel("音量:")
volume_layout.addWidget(volume_label)
# 音量滑块
self.volume_slider = QSlider(Qt.Horizontal)
self.volume_slider.setRange(0, 100)
self.volume_slider.setValue(20)
self.volume_slider.valueChanged.connect(self.adjust_volume)
volume_layout.addWidget(self.volume_slider)
# 将音量控制布局添加到主布局
main_layout.addLayout(volume_layout)
# 添加文件夹选择按钮
self.folder_button = QPushButton("选择文件夹")
self.folder_button.clicked.connect(self.open_folder_dialog)
main_layout.addWidget(self.folder_button)
# 设置主布局
self.setLayout(main_layout)
# 设置窗口大小
self.setGeometry(100, 100, 400, 200)
# 定时器用于更新进度条
self.timer = QTimer()
self.timer.timeout.connect(self.update_progress)
# 打开文件夹对话框
def open_folder_dialog(self):
folder_dialog = QFileDialog()
folder_path = folder_dialog.getExistingDirectory(self, "选择文件夹")
if folder_path:
self.load_songs_from_folder(folder_path)
else:
self.load_songs_from_folder(r"D:\BaiduNetdiskDownload\儿歌")
# 从文件夹加载音频文件
def load_songs_from_folder(self, folder_path):
self.playlist = []
supported_formats = [".mp3", ".wav"] # 支持的音频格式
for root, dirs, files in os.walk(folder_path):
for file in files:
if any(file.endswith(format) for format in supported_formats):
self.playlist.append(os.path.join(root, file))
if self.playlist:
self.current_index = 0
self.load_song(self.current_index)
else:
self.song_info.setText("未找到支持的音频文件")
# 加载歌曲
def load_song(self, index):
if 0 <= index < len(self.playlist):
song_path = self.playlist[index]
self.media_player.setMedia(QMediaContent(QUrl.fromLocalFile(song_path)))
self.song_info.setText(f"当前播放: {os.path.basename(song_path)}")
self.play_pause_button.setText("播放")
self.media_player.play()
# 切换播放/暂停
def toggle_play_pause(self):
if self.media_player.state() == QMediaPlayer.PlayingState:
self.media_player.pause()
self.play_pause_button.setText("播放")
else:
self.media_player.play()
self.play_pause_button.setText("暂停")
# 停止播放
def stop_music(self):
self.media_player.stop()
self.play_pause_button.setText("播放")
# 上一首
def prev_song(self):
if self.current_index > 0:
self.current_index -= 1
self.load_song(self.current_index)
# 下一首
def next_song(self):
if self.current_index < len(self.playlist) - 1:
self.current_index += 1
self.load_song(self.current_index)
# 调整音量
def adjust_volume(self, value):
self.media_player.setVolume(value)
# 跳转到指定位置
def seek_position(self, value):
if self.media_player.duration() > 0:
position = int((value / 100) * self.media_player.duration())
self.media_player.setPosition(position)
# 更新进度条
def update_progress(self):
if self.media_player.duration() > 0:
progress = int((self.media_player.position() / self.media_player.duration()) * 100)
self.progress_slider.setValue(progress)
# 播放状态改变时启动或停止定时器
def media_state_changed(self, state):
if state == QMediaPlayer.PlayingState:
self.timer.start(1000) # 每秒更新一次进度条
else:
self.timer.stop()
# 初始化媒体播放器信号连接
def init_media_player(self):
self.media_player.stateChanged.connect(self.media_state_changed)
# 主程序
if __name__ == "__main__":
app = QApplication(sys.argv)
player = MusicPlayer()
player.init_media_player() # 初始化媒体播放器信号连接
player.show()
sys.exit(app.exec_())
再优化:播放当前结束,自动跳转下一首;
import sys
import os
from PyQt5.QtWidgets import (
QApplication, QWidget, QPushButton, QHBoxLayout, QVBoxLayout, QSlider, QLabel, QFileDialog
)
from PyQt5.QtCore import Qt, QUrl, QTimer
from PyQt5.QtMultimedia import QMediaPlayer, QMediaContent
class MusicPlayer(QWidget):
def __init__(self):
super().__init__()
# 初始化媒体播放器
self.media_player = QMediaPlayer()
self.playlist = [] # 播放列表
self.current_index = 0 # 当前播放的歌曲索引
# 设置窗口标题
self.setWindowTitle("本地音乐播放器")
# 创建主布局
main_layout = QVBoxLayout()
# 歌曲信息
self.song_info = QLabel("当前播放: 无")
self.song_info.setAlignment(Qt.AlignCenter)
main_layout.addWidget(self.song_info)
# 进度条
self.progress_slider = QSlider(Qt.Horizontal)
self.progress_slider.setRange(0, 100)
self.progress_slider.setValue(0)
self.progress_slider.sliderMoved.connect(self.seek_position)
main_layout.addWidget(self.progress_slider)
# 控制按钮布局
control_layout = QHBoxLayout()
# 上一首按钮
self.prev_button = QPushButton("上一首")
self.prev_button.clicked.connect(self.prev_song)
control_layout.addWidget(self.prev_button)
# 播放/暂停按钮
self.play_pause_button = QPushButton("播放")
self.play_pause_button.clicked.connect(self.toggle_play_pause)
control_layout.addWidget(self.play_pause_button)
# 停止按钮
self.stop_button = QPushButton("停止")
self.stop_button.clicked.connect(self.stop_music)
control_layout.addWidget(self.stop_button)
# 下一首按钮
self.next_button = QPushButton("下一首")
self.next_button.clicked.connect(self.next_song)
control_layout.addWidget(self.next_button)
# 将控制按钮布局添加到主布局
main_layout.addLayout(control_layout)
# 音量控制布局
volume_layout = QHBoxLayout()
# 音量标签
volume_label = QLabel("音量:")
volume_layout.addWidget(volume_label)
# 音量滑块
self.volume_slider = QSlider(Qt.Horizontal)
self.volume_slider.setRange(0, 100)
self.volume_slider.setValue(20)
self.volume_slider.valueChanged.connect(self.adjust_volume)
volume_layout.addWidget(self.volume_slider)
# 将音量控制布局添加到主布局
main_layout.addLayout(volume_layout)
# 添加文件夹选择按钮
self.folder_button = QPushButton("选择文件夹")
self.folder_button.clicked.connect(self.open_folder_dialog)
main_layout.addWidget(self.folder_button)
# 设置主布局
self.setLayout(main_layout)
# 设置窗口大小
self.setGeometry(100, 100, 400, 200)
# 定时器用于更新进度条
self.timer = QTimer()
self.timer.timeout.connect(self.update_progress)
# 初始化媒体播放器信号连接
self.init_media_player()
# 打开文件夹对话框
def open_folder_dialog(self):
folder_dialog = QFileDialog()
folder_path = folder_dialog.getExistingDirectory(self, "选择文件夹")
if folder_path:
self.load_songs_from_folder(folder_path)
else:
self.load_songs_from_folder(r"D:\BaiduNetdiskDownload\儿歌")
# 从文件夹加载音频文件
def load_songs_from_folder(self, folder_path):
self.playlist = []
supported_formats = [".mp3", ".wav"] # 支持的音频格式
for root, dirs, files in os.walk(folder_path):
for file in files:
if any(file.endswith(format) for format in supported_formats):
self.playlist.append(os.path.join(root, file))
if self.playlist:
self.current_index = 0
self.load_song(self.current_index)
else:
self.song_info.setText("未找到支持的音频文件")
# 加载歌曲
def load_song(self, index):
if 0 <= index < len(self.playlist):
song_path = self.playlist[index]
self.media_player.setMedia(QMediaContent(QUrl.fromLocalFile(song_path)))
self.song_info.setText(f"当前播放: {os.path.basename(song_path)}")
self.play_pause_button.setText("播放")
self.media_player.play()
# 切换播放/暂停
def toggle_play_pause(self):
if self.media_player.state() == QMediaPlayer.PlayingState:
self.media_player.pause()
self.play_pause_button.setText("播放")
else:
self.media_player.play()
self.play_pause_button.setText("暂停")
# 停止播放
def stop_music(self):
self.media_player.stop()
self.play_pause_button.setText("播放")
# 上一首
def prev_song(self):
if self.current_index > 0:
self.current_index -= 1
self.load_song(self.current_index)
# 下一首
def next_song(self):
if self.current_index < len(self.playlist) - 1:
self.current_index += 1
self.load_song(self.current_index)
else:
# 如果已经是最后一首,停止播放
self.stop_music()
# 调整音量
def adjust_volume(self, value):
self.media_player.setVolume(value)
# 跳转到指定位置
def seek_position(self, value):
if self.media_player.duration() > 0:
position = int((value / 100) * self.media_player.duration())
self.media_player.setPosition(position)
# 更新进度条
def update_progress(self):
if self.media_player.duration() > 0:
progress = int((self.media_player.position() / self.media_player.duration()) * 100)
self.progress_slider.setValue(progress)
# 播放状态改变时启动或停止定时器
def media_state_changed(self, state):
if state == QMediaPlayer.PlayingState:
self.timer.start(1000) # 每秒更新一次进度条
else:
self.timer.stop()
# 媒体状态改变时检查是否播放结束
def media_status_changed(self, status):
if status == QMediaPlayer.EndOfMedia:
self.next_song() # 自动播放下一首
# 初始化媒体播放器信号连接
def init_media_player(self):
self.media_player.stateChanged.connect(self.media_state_changed)
self.media_player.mediaStatusChanged.connect(self.media_status_changed)
# 主程序
if __name__ == "__main__":
app = QApplication(sys.argv)
player = MusicPlayer()
player.show()
sys.exit(app.exec_())
时间显示
import sys
import os
from PyQt5.QtWidgets import (
QApplication, QWidget, QPushButton, QHBoxLayout, QVBoxLayout, QSlider, QLabel, QFileDialog
)
from PyQt5.QtCore import Qt, QUrl, QTimer
from PyQt5.QtMultimedia import QMediaPlayer, QMediaContent
class MusicPlayer(QWidget):
def __init__(self):
super().__init__()
# 初始化媒体播放器
self.media_player = QMediaPlayer()
self.playlist = [] # 播放列表
self.current_index = 0 # 当前播放的歌曲索引
# 设置窗口标题
self.setWindowTitle("本地音乐播放器")
# 创建主布局
main_layout = QVBoxLayout()
# 歌曲信息
self.song_info = QLabel("当前播放: 无")
self.song_info.setAlignment(Qt.AlignCenter)
main_layout.addWidget(self.song_info)
# 时间显示
self.time_label = QLabel("00:00 / 00:00")
self.time_label.setAlignment(Qt.AlignCenter)
main_layout.addWidget(self.time_label)
# 进度条
self.progress_slider = QSlider(Qt.Horizontal)
self.progress_slider.setRange(0, 100)
self.progress_slider.setValue(0)
self.progress_slider.sliderMoved.connect(self.seek_position)
main_layout.addWidget(self.progress_slider)
# 控制按钮布局
control_layout = QHBoxLayout()
# 上一首按钮
self.prev_button = QPushButton("上一首")
self.prev_button.clicked.connect(self.prev_song)
control_layout.addWidget(self.prev_button)
# 播放/暂停按钮
self.play_pause_button = QPushButton("播放")
self.play_pause_button.clicked.connect(self.toggle_play_pause)
control_layout.addWidget(self.play_pause_button)
# 停止按钮
self.stop_button = QPushButton("停止")
self.stop_button.clicked.connect(self.stop_music)
control_layout.addWidget(self.stop_button)
# 下一首按钮
self.next_button = QPushButton("下一首")
self.next_button.clicked.connect(self.next_song)
control_layout.addWidget(self.next_button)
# 将控制按钮布局添加到主布局
main_layout.addLayout(control_layout)
# 音量控制布局
volume_layout = QHBoxLayout()
# 音量标签
volume_label = QLabel("音量:")
volume_layout.addWidget(volume_label)
# 音量滑块
self.volume_slider = QSlider(Qt.Horizontal)
self.volume_slider.setRange(0, 100)
self.volume_slider.setValue(50)
self.volume_slider.valueChanged.connect(self.adjust_volume)
volume_layout.addWidget(self.volume_slider)
# 将音量控制布局添加到主布局
main_layout.addLayout(volume_layout)
# 添加文件夹选择按钮
self.folder_button = QPushButton("选择文件夹")
self.folder_button.clicked.connect(self.open_folder_dialog)
main_layout.addWidget(self.folder_button)
# 设置主布局
self.setLayout(main_layout)
# 设置窗口大小
self.setGeometry(100, 100, 400, 250)
# 定时器用于更新进度条和时间显示
self.timer = QTimer()
self.timer.timeout.connect(self.update_progress_and_time)
# 初始化媒体播放器信号连接
self.init_media_player()
# 打开文件夹对话框
def open_folder_dialog(self):
folder_dialog = QFileDialog()
folder_path = folder_dialog.getExistingDirectory(self, "选择文件夹")
if folder_path:
self.load_songs_from_folder(folder_path)
# 从文件夹加载音频文件
def load_songs_from_folder(self, folder_path):
self.playlist = []
supported_formats = [".mp3", ".wav"] # 支持的音频格式
for root, dirs, files in os.walk(folder_path):
for file in files:
if any(file.endswith(format) for format in supported_formats):
self.playlist.append(os.path.join(root, file))
if self.playlist:
self.current_index = 0
self.load_song(self.current_index)
else:
self.song_info.setText("未找到支持的音频文件")
# 加载歌曲
def load_song(self, index):
if 0 <= index < len(self.playlist):
song_path = self.playlist[index]
self.media_player.setMedia(QMediaContent(QUrl.fromLocalFile(song_path)))
self.song_info.setText(f"当前播放: {os.path.basename(song_path)}")
self.play_pause_button.setText("播放")
self.media_player.play()
# 切换播放/暂停
def toggle_play_pause(self):
if self.media_player.state() == QMediaPlayer.PlayingState:
self.media_player.pause()
self.play_pause_button.setText("播放")
else:
self.media_player.play()
self.play_pause_button.setText("暂停")
# 停止播放
def stop_music(self):
self.media_player.stop()
self.play_pause_button.setText("播放")
# 上一首
def prev_song(self):
if self.current_index > 0:
self.current_index -= 1
self.load_song(self.current_index)
# 下一首
def next_song(self):
if self.current_index < len(self.playlist) - 1:
self.current_index += 1
self.load_song(self.current_index)
else:
# 如果已经是最后一首,停止播放
self.stop_music()
# 调整音量
def adjust_volume(self, value):
self.media_player.setVolume(value)
# 跳转到指定位置
def seek_position(self, value):
if self.media_player.duration() > 0:
position = int((value / 100) * self.media_player.duration())
self.media_player.setPosition(position)
# 更新进度条和时间显示
def update_progress_and_time(self):
if self.media_player.duration() > 0:
# 更新进度条
progress = int((self.media_player.position() / self.media_player.duration()) * 100)
self.progress_slider.setValue(progress)
# 更新时间显示
current_time = self.format_time(self.media_player.position())
total_time = self.format_time(self.media_player.duration())
self.time_label.setText(f"{current_time} / {total_time}")
# 格式化时间(毫秒 -> 分钟:秒)
def format_time(self, milliseconds):
seconds = int(milliseconds / 1000)
minutes = seconds // 60
seconds = seconds % 60
return f"{minutes:02}:{seconds:02}"
# 播放状态改变时启动或停止定时器
def media_state_changed(self, state):
if state == QMediaPlayer.PlayingState:
self.timer.start(1000) # 每秒更新一次进度条和时间
else:
self.timer.stop()
# 媒体状态改变时检查是否播放结束
def media_status_changed(self, status):
if status == QMediaPlayer.EndOfMedia:
self.next_song() # 自动播放下一首
# 初始化媒体播放器信号连接
def init_media_player(self):
self.media_player.stateChanged.connect(self.media_state_changed)
self.media_player.mediaStatusChanged.connect(self.media_status_changed)
# 主程序
if __name__ == "__main__":
app = QApplication(sys.argv)
player = MusicPlayer()
player.show()
sys.exit(app.exec_())
效果展示