【Pyqt5】水平布局与垂直布局及其交叉展示及实战音乐播放器UI

发布于:2025-03-16 ⋅ 阅读:(16) ⋅ 点赞:(0)

感受一下Pyqt5的水平布局与垂直布局及其交叉展示

需求:

  1. 4个按钮水平排放
  2. 4个按钮垂直排放
  3. 水平排放与垂直排放并用
  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_())

效果展示
在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到