20254106 实验四《Python实验设计》实验报告

20254106 2025-2026-6 《Python程序设计》实验4报告

课程:《Python程序设计》
班级: 2541
姓名: 谢林儒
学号:20254106
实验教师:王志强
实验日期:2026年6月13日
必修/选修: 专选课

一、实验内容

Python综合应用:爬虫、数据处理、可视化、机器学习、神经网络、游戏、网络安全等。
例如:编写从社交网络爬取数据,实现可视化舆情监控或者情感分析。
例如:利用公开数据集,开展图像分类、恶意软件检测等
例如:利用Python库,基于OCR技术实现自动化提取图片中数据,并填入excel中。
例如:爬取天气数据,实现自动化微信提醒
例如:利用爬虫,实现自动化下载网站视频、文件等。
例如:编写小游戏:坦克大战、贪吃蛇、扫雷等等
注:在Windows/Linux系统上使用VIM、PDB、IDLE、Pycharm等工具编程实现。
评分标准:
(1)程序能运行,功能丰富(至少5个功能)。(需求提交源代码,并建议录制程序运行的视频)15分
(2)综合实践报告,要体现实验分析、设计、实现过程、结果等信息,格式规范,逻辑清晰,结构合理。20分。
(3)在实践报告中,需要对全课进行总结,并写课程感想体会、意见和建议等。10分

二、实验过程

前传:完整代码展示

点击查看代码
import os
import sys
import time
import random
import configparser
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtMultimedia import *


class MusicPlayer(QWidget):
    def __init__(self):
        super().__init__()
        self.__initialize()

    def __initialize(self):
        # 窗口设置
        self.setWindowTitle('🎀 粉色音乐播放器 🎀')

        self.songs_list = []
        self.song_formats = ['mp3', 'm4a', 'flac', 'wav', 'ogg']
        self.setting_filename = 'setting.ini'
        self.player = QMediaPlayer()
        self.cur_path = os.path.abspath(os.path.dirname(__file__))
        self.cur_playing_song = ''
        self.is_switching = False
        self.is_pause = True

        # ----- 界面控件 -----
        self.now_playing_label = QLabel('🌸 未播放 🌸')
        self.now_playing_label.setAlignment(Qt.AlignCenter)

        self.label_current = QLabel('00:00')
        self.label_total = QLabel('00:00')
        self.label_current.setAlignment(Qt.AlignCenter)
        self.label_total.setAlignment(Qt.AlignCenter)

        self.slider = QSlider(Qt.Horizontal)
        self.slider.sliderMoved[int].connect(lambda pos: self.player.setPosition(pos))

        self.volume_slider = QSlider(Qt.Horizontal)
        self.volume_slider.setRange(0, 100)
        self.volume_slider.setValue(70)
        self.volume_slider.valueChanged.connect(self.player.setVolume)
        self.volume_label = QLabel("🔊")

        self.play_button = QPushButton('▶ 播放')
        self.play_button.clicked.connect(self.playMusic)
        self.preview_button = QPushButton('⏮ 上一首')
        self.preview_button.clicked.connect(self.previewMusic)
        self.next_button = QPushButton('⏭ 下一首')
        self.next_button.clicked.connect(self.nextMusic)
        self.open_button = QPushButton('📂 打开文件夹')
        self.open_button.clicked.connect(self.openDir)

        self.cmb = QComboBox()
        self.cmb.addItems(['顺序播放', '单曲循环', '随机播放'])

        self.song_list_widget = QListWidget()
        self.song_list_widget.itemDoubleClicked.connect(self.doubleClicked)

        # ----- 粉色样式 -----
        self.setStyleSheet("""
            QWidget {
                background-color: #ffe4ec;
                font-family: "Microsoft YaHei", "Segoe UI", "Comic Sans MS", cursive;
            }
            QLabel {
                color: #b34180;
                font-size: 12px;
            }
            QPushButton {
                background-color: #ffb7c5;
                color: #8b3a62;
                border: none;
                border-radius: 15px;
                padding: 8px 15px;
                font-size: 12px;
                font-weight: bold;
            }
            QPushButton:hover {
                background-color: #ff9eb0;
            }
            QPushButton:pressed {
                background-color: #e6849a;
            }
            QListWidget {
                background-color: #fff0f3;
                border: 2px solid #ffc0cb;
                border-radius: 10px;
                color: #8b3a62;
                font-size: 12px;
            }
            QListWidget::item:selected {
                background-color: #ffc0cb;
                color: #5c2e46;
            }
            QListWidget::item:hover {
                background-color: #ffe0e7;
            }
            QSlider::groove:horizontal {
                border: 1px solid #ffb7c5;
                height: 6px;
                background: #ffe0e7;
                border-radius: 3px;
            }
            QSlider::handle:horizontal {
                background: #ff88aa;
                width: 14px;
                height: 14px;
                margin: -4px 0;
                border-radius: 7px;
            }
            QSlider::handle:horizontal:hover {
                background: #ff6699;
            }
            QComboBox {
                background-color: #ffb7c5;
                color: #8b3a62;
                border-radius: 12px;
                padding: 5px 10px;
                font-weight: bold;
            }
            QComboBox::drop-down {
                border: none;
            }
            QComboBox QAbstractItemView {
                background-color: #ffe4ec;
                color: #8b3a62;
                selection-background-color: #ffc0cb;
            }
        """)

        # ----- 布局 -----
        main_layout = QVBoxLayout()
        self.setLayout(main_layout)
        main_layout.addWidget(self.now_playing_label)
        main_layout.addWidget(self.song_list_widget, 5)

        time_layout = QHBoxLayout()
        time_layout.addWidget(self.label_current)
        time_layout.addWidget(self.slider)
        time_layout.addWidget(self.label_total)
        main_layout.addLayout(time_layout)

        control_layout = QHBoxLayout()
        control_layout.addWidget(self.play_button)
        control_layout.addWidget(self.preview_button)
        control_layout.addWidget(self.next_button)
        control_layout.addWidget(self.cmb)
        control_layout.addStretch()
        control_layout.addWidget(self.volume_label)
        control_layout.addWidget(self.volume_slider)
        main_layout.addLayout(control_layout)

        file_layout = QHBoxLayout()
        file_layout.addWidget(self.open_button)
        main_layout.addLayout(file_layout)

        self.status_label = QLabel('✨ 欢迎使用粉色音乐播放器 ✨')
        self.status_label.setAlignment(Qt.AlignCenter)
        self.status_label.setStyleSheet("color: #b34180; font-size: 11px; padding: 5px;")
        main_layout.addWidget(self.status_label)

        # ----- 初始化 -----
        self.loadSetting()
        self.timer = QTimer(self)
        self.timer.timeout.connect(self.updateProgressByMode)
        self.timer.start(1000)
        self.player.setVolume(self.volume_slider.value())

    # ---------- 播放核心 ----------
    def updateProgressByMode(self):
        if (not self.is_pause) and (not self.is_switching):
            if self.player.duration() > 0:
                self.slider.setMaximum(self.player.duration())
            self.slider.setValue(self.player.position())
        self.label_current.setText(time.strftime('%M:%S', time.localtime(self.player.position() / 1000)))
        self.label_total.setText(time.strftime('%M:%S', time.localtime(self.player.duration() / 1000)))
        if self.song_list_widget.count() == 0:
            return
        if (not self.is_pause) and (not self.is_switching):
            if self.player.duration() > 0 and self.player.position() >= self.player.duration() - 50:
                mode = self.cmb.currentIndex()
                if mode == 0:
                    self.nextMusic()
                elif mode == 1:
                    self.is_switching = True
                    self.player.setPosition(0)
                    self.player.play()
                    self.is_switching = False
                elif mode == 2:
                    self.is_switching = True
                    rand_row = random.randint(0, self.song_list_widget.count() - 1)
                    self.song_list_widget.setCurrentRow(rand_row)
                    self.setCurPlaying()
                    self.player.play()
                    self.is_switching = False

    def setCurPlaying(self):
        if self.song_list_widget.currentRow() >= 0 and self.songs_list:
            self.cur_playing_song = self.songs_list[self.song_list_widget.currentRow()][1]
            self.player.setMedia(QMediaContent(QUrl.fromLocalFile(self.cur_playing_song)))
            song_name = self.songs_list[self.song_list_widget.currentRow()][0]
            self.now_playing_label.setText(f"🎵 正在播放:{song_name}")

    def playMusic(self):
        if self.song_list_widget.count() == 0:
            QMessageBox.information(self, "提示", "当前文件夹没有音乐文件,请先打开一个包含音乐的文件夹。")
            return
        if self.player.media().isNull():
            self.setCurPlaying()
        if self.is_pause or self.is_switching:
            self.player.play()
            self.is_pause = False
            self.play_button.setText('⏸ 暂停')
        else:
            self.player.pause()
            self.is_pause = True
            self.play_button.setText('▶ 播放')

    def previewMusic(self):
        if self.song_list_widget.count() == 0:
            QMessageBox.information(self, "提示", "没有歌曲,无法上一首。")
            return
        self.slider.setValue(0)
        row = self.song_list_widget.currentRow()
        new_row = row - 1 if row > 0 else self.song_list_widget.count() - 1
        self.song_list_widget.setCurrentRow(new_row)
        self.is_switching = True
        self.setCurPlaying()
        if not self.is_pause:
            self.player.play()
        self.is_switching = False

    def nextMusic(self):
        if self.song_list_widget.count() == 0:
            QMessageBox.information(self, "提示", "没有歌曲,无法下一首。")
            return
        self.slider.setValue(0)
        row = self.song_list_widget.currentRow()
        new_row = row + 1 if row < self.song_list_widget.count() - 1 else 0
        self.song_list_widget.setCurrentRow(new_row)
        self.is_switching = True
        self.setCurPlaying()
        if not self.is_pause:
            self.player.play()
        self.is_switching = False

    def doubleClicked(self):
        self.slider.setValue(0)
        self.is_switching = True
        self.setCurPlaying()
        self.player.play()
        self.is_pause = False
        self.play_button.setText('⏸ 暂停')
        self.is_switching = False

    # ---------- 文件夹管理 ----------
    def openDir(self):
        path = QFileDialog.getExistingDirectory(self, "选择音乐文件夹", self.cur_path)
        if path:
            self.cur_path = path
            self.showMusicList()
            self.player.stop()
            self.is_pause = True
            self.play_button.setText('▶ 播放')
            self.now_playing_label.setText("🌸 未播放 🌸")
            self.slider.setValue(0)
            self.label_current.setText('00:00')
            self.label_total.setText('00:00')
            self.updateSetting()

    def showMusicList(self):
        self.song_list_widget.clear()
        self.songs_list.clear()
        if not os.path.isdir(self.cur_path):
            return
        for filename in os.listdir(self.cur_path):
            ext = filename.split('.')[-1].lower()
            if ext in self.song_formats:
                fullpath = os.path.join(self.cur_path, filename).replace('\\', '/')
                self.songs_list.append([filename, fullpath])
                self.song_list_widget.addItem(filename)
        if self.songs_list:
            self.song_list_widget.setCurrentRow(0)
            self.setCurPlaying()
        else:
            self.now_playing_label.setText("🎵 当前文件夹没有音乐文件")

    # ---------- 设置记忆 ----------
    def loadSetting(self):
        if os.path.isfile(self.setting_filename):
            config = configparser.ConfigParser()
            config.read(self.setting_filename)
            if config.has_option('MusicPlayer', 'PATH'):
                self.cur_path = config.get('MusicPlayer', 'PATH')
            if config.has_option('MusicPlayer', 'geometry'):
                geometry = config.get('MusicPlayer', 'geometry')
                self.restoreGeometry(QByteArray.fromHex(geometry.encode()))
            self.showMusicList()

    def updateSetting(self):
        config = configparser.ConfigParser()
        config.read(self.setting_filename)
        if not config.has_section('MusicPlayer'):
            config.add_section('MusicPlayer')
        config.set('MusicPlayer', 'PATH', self.cur_path)
        config.set('MusicPlayer', 'geometry', self.saveGeometry().toHex().data().decode())
        with open(self.setting_filename, 'w') as f:
            config.write(f)

    def closeEvent(self, event):
        self.updateSetting()
        event.accept()


if __name__ == '__main__':
    # 屏蔽libpng警告(可选)
    import warnings

    warnings.filterwarnings("ignore", category=UserWarning, module="libpng")

    app = QApplication(sys.argv)
    window = MusicPlayer()
    window.show()
    sys.exit(app.exec_())

(一)实验设计思路

  1. 实验设计背景

本次实验我选择编写音乐播放器。听音乐是放松心情、提高效率的重要方式。本次实验选择自己动手设计一款本地音乐播放器,既能巩固课堂所学,也能打造一个符合个人审美、轻量简洁的工具。
灵感来源于小红书有关音乐播放器的简易代码编写,基于简单代码,通过不断与LLM沟通需要,进行优化升级。

  1. 关键技术
技术 用途
PyQt5.QtMultimedia 窗口、按钮、列表、布局等基础控件
PyQt5.QtCore QMediaPlayer音频播放引擎
configparser QTimer定时器、QUrl路径转换、Qt对齐常量
os / time 读写setting.ini配置文件
PyQt5.QtWidgets 文件路径操作、时间格式化
  1. 功能模块介绍

(1)界面模块:使用PyQt5构建主窗口,通过QSS实现粉色界面颜色
(2)文件扫描模块:遍历指定文件夹,过滤.mp3/.m4a/.flac/.wav/.ogg格式
(3)播放控制模块:播放/暂停、上一首/下一首、进度条拖拽、音量调节
(4)播放模式模块:顺序播放、单曲循环、随机播放(通过下拉框切换)
(5)定时更新模块:每秒刷新进度条、当前时间、总时长,并触发自动切歌
(6)配置记忆模块:保存/恢复上次打开的文件夹路径、窗口位置及大小

(二)实现过程

1.环境配置与库安装

在PyCharm中创建项目,在Terminal中执行以下命令安装依赖库(使用清华镜像加速):
pip install PyQt5 PyQt5-sip PyQtMultimedia -i https://pypi.tuna.tsinghua.edu.cn/simple

PyQt5 安装成功

2.编写初始化代码与界面布局
①创建MusicPlayer类,在__initialize方法中:设置窗口标题、尺寸、图标(可选)

11

②定义self.songs_list存储歌曲路径,self.song_formats支持的后缀

12

③创建QMediaPlayer对象,实例化所有控件:标签、进度条、按钮、下拉框、列表框

点击查看代码
        self.now_playing_label = QLabel('🌸 未播放 🌸')
        self.now_playing_label.setAlignment(Qt.AlignCenter)

        self.label_current = QLabel('00:00')
        self.label_total = QLabel('00:00')
        self.label_current.setAlignment(Qt.AlignCenter)
        self.label_total.setAlignment(Qt.AlignCenter)

        self.slider = QSlider(Qt.Horizontal)
        self.slider.sliderMoved[int].connect(lambda pos: self.player.setPosition(pos))

        self.volume_slider = QSlider(Qt.Horizontal)
        self.volume_slider.setRange(0, 100)
        self.volume_slider.setValue(70)
        self.volume_slider.valueChanged.connect(self.player.setVolume)
        self.volume_label = QLabel("🔊")

        self.play_button = QPushButton('▶ 播放')
        self.play_button.clicked.connect(self.playMusic)
        self.preview_button = QPushButton('⏮ 上一首')
        self.preview_button.clicked.connect(self.previewMusic)
        self.next_button = QPushButton('⏭ 下一首')
        self.next_button.clicked.connect(self.nextMusic)
        self.open_button = QPushButton('📂 打开文件夹')
        self.open_button.clicked.connect(self.openDir)

        self.cmb = QComboBox()
        self.cmb.addItems(['顺序播放', '单曲循环', '随机播放'])

        self.song_list_widget = QListWidget()
        self.song_list_widget.itemDoubleClicked.connect(self.doubleClicked)

④应用全局QSS样式表(粉色主题)

点击查看代码
self.setStyleSheet("""
            QWidget {
                background-color: #ffe4ec;
                font-family: "Microsoft YaHei", "Segoe UI", "Comic Sans MS", cursive;
            }
            QLabel {
                color: #b34180;
                font-size: 12px;
            }
            QPushButton {
                background-color: #ffb7c5;
                color: #8b3a62;
                border: none;
                border-radius: 15px;
                padding: 8px 15px;
                font-size: 12px;
                font-weight: bold;
            }
            QPushButton:hover {
                background-color: #ff9eb0;
            }
            QPushButton:pressed {
                background-color: #e6849a;
            }
            QListWidget {
                background-color: #fff0f3;
                border: 2px solid #ffc0cb;
                border-radius: 10px;
                color: #8b3a62;
                font-size: 12px;
            }
            QListWidget::item:selected {
                background-color: #ffc0cb;
                color: #5c2e46;
            }
            QListWidget::item:hover {
                background-color: #ffe0e7;
            }
            QSlider::groove:horizontal {
                border: 1px solid #ffb7c5;
                height: 6px;
                background: #ffe0e7;
                border-radius: 3px;
            }
            QSlider::handle:horizontal {
                background: #ff88aa;
                width: 14px;
                height: 14px;
                margin: -4px 0;
                border-radius: 7px;
            }
            QSlider::handle:horizontal:hover {
                background: #ff6699;
            }
            QComboBox {
                background-color: #ffb7c5;
                color: #8b3a62;
                border-radius: 12px;
                padding: 5px 10px;
                font-weight: bold;
            }
            QComboBox::drop-down {
                border: none;
            }
            QComboBox QAbstractItemView {
                background-color: #ffe4ec;
                color: #8b3a62;
                selection-background-color: #ffc0cb;
            }
        """)

⑤使用QVBoxLayout和QHBoxLayout进行嵌套布局

点击查看代码
main_layout = QVBoxLayout()
        self.setLayout(main_layout)
        main_layout.addWidget(self.now_playing_label)
        main_layout.addWidget(self.song_list_widget, 5)

        time_layout = QHBoxLayout()
        time_layout.addWidget(self.label_current)
        time_layout.addWidget(self.slider)
        time_layout.addWidget(self.label_total)
        main_layout.addLayout(time_layout)

        control_layout = QHBoxLayout()
        control_layout.addWidget(self.play_button)
        control_layout.addWidget(self.preview_button)
        control_layout.addWidget(self.next_button)
        control_layout.addWidget(self.cmb)
        control_layout.addStretch()
        control_layout.addWidget(self.volume_label)
        control_layout.addWidget(self.volume_slider)
        main_layout.addLayout(control_layout)

        file_layout = QHBoxLayout()
        file_layout.addWidget(self.open_button)
        main_layout.addLayout(file_layout)

        self.status_label = QLabel('✨ 欢迎使用粉色音乐播放器 ✨')
        self.status_label.setAlignment(Qt.AlignCenter)
        self.status_label.setStyleSheet("color: #b34180; font-size: 11px; padding: 5px;")
        main_layout.addWidget(self.status_label)

3.实现音乐文件夹扫描

清空列表控件和songs_list;
遍历self.cur_path下的所有文件;
提取后缀名,如果匹配self.song_formats,则添加显示名到QListWidget,同时存储完整路径到songs_list;
如果有歌曲,默认选中第一首并调用setCurPlaying()预加载。

16

4.播放核心逻辑
(1)播放/暂停
如果列表为空则弹出提示;
如果播放器未加载媒体则先调用setCurPlaying;
根据self.is_pause状态调用player.play()或player.pause(),并切换按钮文字。
(2)进度更新与自动切歌
创建QTimer,每1秒触发updateProgressByMode方法:
获取当前播放位置和总时长,更新时间标签;
更新进度条的值和最大值;
检查歌曲是否播放结束(position >= duration - 50),根据当前播放模式执行;
顺序播放:调用nextMusic();
单曲循环:重置player.setPosition(0)后继续播放;
随机播放:随机选择列表中的一首,调用setCurPlaying()后播放。

点击查看代码
 def updateProgressByMode(self):
        if (not self.is_pause) and (not self.is_switching):
            if self.player.duration() > 0:
                self.slider.setMaximum(self.player.duration())
            self.slider.setValue(self.player.position())
        self.label_current.setText(time.strftime('%M:%S', time.localtime(self.player.position() / 1000)))
        self.label_total.setText(time.strftime('%M:%S', time.localtime(self.player.duration() / 1000)))
        if self.song_list_widget.count() == 0:
            return
        if (not self.is_pause) and (not self.is_switching):
            if self.player.duration() > 0 and self.player.position() >= self.player.duration() - 50:
                mode = self.cmb.currentIndex()
                if mode == 0:
                    self.nextMusic()
                elif mode == 1:
                    self.is_switching = True
                    self.player.setPosition(0)
                    self.player.play()
                    self.is_switching = False
                elif mode == 2:
                    self.is_switching = True
                    rand_row = random.randint(0, self.song_list_widget.count() - 1)
                    self.song_list_widget.setCurrentRow(rand_row)
                    self.setCurPlaying()
                    self.player.play()
                    self.is_switching = False

    def setCurPlaying(self):
        if self.song_list_widget.currentRow() >= 0 and self.songs_list:
            self.cur_playing_song = self.songs_list[self.song_list_widget.currentRow()][1]
            self.player.setMedia(QMediaContent(QUrl.fromLocalFile(self.cur_playing_song)))
            song_name = self.songs_list[self.song_list_widget.currentRow()][0]
            self.now_playing_label.setText(f"🎵 正在播放:{song_name}")

    def playMusic(self):
        if self.song_list_widget.count() == 0:
            QMessageBox.information(self, "提示", "当前文件夹没有音乐文件,请先打开一个包含音乐的文件夹。")
            return
        if self.player.media().isNull():
            self.setCurPlaying()
        if self.is_pause or self.is_switching:
            self.player.play()
            self.is_pause = False
            self.play_button.setText('⏸ 暂停')
        else:
            self.player.pause()
            self.is_pause = True
            self.play_button.setText('▶ 播放')

    def previewMusic(self):
        if self.song_list_widget.count() == 0:
            QMessageBox.information(self, "提示", "没有歌曲,无法上一首。")
            return
        self.slider.setValue(0)
        row = self.song_list_widget.currentRow()
        new_row = row - 1 if row > 0 else self.song_list_widget.count() - 1
        self.song_list_widget.setCurrentRow(new_row)
        self.is_switching = True
        self.setCurPlaying()
        if not self.is_pause:
            self.player.play()
        self.is_switching = False

    def nextMusic(self):
        if self.song_list_widget.count() == 0:
            QMessageBox.information(self, "提示", "没有歌曲,无法下一首。")
            return
        self.slider.setValue(0)
        row = self.song_list_widget.currentRow()
        new_row = row + 1 if row < self.song_list_widget.count() - 1 else 0
        self.song_list_widget.setCurrentRow(new_row)
        self.is_switching = True
        self.setCurPlaying()
        if not self.is_pause:
            self.player.play()
        self.is_switching = False

    def doubleClicked(self):
        self.slider.setValue(0)
        self.is_switching = True
        self.setCurPlaying()
        self.player.play()
        self.is_pause = False
        self.play_button.setText('⏸ 暂停')
        self.is_switching = False

5.添加音量控制与记忆功能
创建self.volume_slider(范围0-100),初始值70,绑定valueChanged信号到self.player.setVolume;
使用configparser读写setting.ini文件,在loadSetting中读取PATH和geometry,在closeEvent中保存。

6.完整运行测试

运行程序,依次测试以下功能:
(1)点击“打开文件夹”,选择包含MP3的目录 → 列表正确显示
(2)双击歌曲 → 开始播放,进度条走动,时间正常
(3)点击“暂停” → 音乐停止,按钮变为“播放”
(4)拖动进度条 → 跳转到指定位置
(5)调节音量滑块 → 声音大小变化
(6)切换播放模式为“单曲循环” → 歌曲结束后自动重播
(7)切换为“随机播放” → 结束后随机跳转
(8)关闭窗口重新打开 → 窗口位置和上次打开的文件夹被恢复

三、实验结果

程序运行视频链接~
1.主窗口

(1)主色调:浅粉色背景(#ffe4ec)、樱花粉按钮(#ffb7c5)、桃粉色滑块(#ff88aa)
(2)布局结构(从上到下):

  • 顶部:当前播放歌曲名(带花朵符号)
  • 中部:歌曲列表(圆角、粉边)
  • 中下部:时间标签 + 进度条 + 总时长
  • 下部第一行:播放按钮、上一首、下一首、播放模式下拉框、音量滑块
  • 下部第二行:打开文件夹按钮
  • 底部:状态提示栏
  • 字体:优先使用“微软雅黑”或“Comic Sans MS”,按钮文字加粗

1
(运行程序后的主窗口全貌,歌曲列表为空的状态)

2
(打开一个包含音乐文件的文件夹后,歌曲列表填充的效果)

2.播放模式切换下拉框

6a7a35e4d1580e9ead7e8cefc5e9f114

3.播放错误提醒

播放

4.正常播放

正常运行

四、实验过程中遇到的问题和解决过程

  • 问题1:
    在PyCharm中直接运行代码,提示ImportError: DLL load failed while importing QtGui: 找不到指定的模块。
  • 问题1解决方案:
    (1)在Terminal中执行pip uninstall PyQt5 PyQt5-sip PyQt5-Qt5 -y彻底卸载;
    (2)重新使用国内清华镜像源安装:pip install PyQt5 -i https://pypi.tuna.tsinghua.edu.cn/simple
    (3)安装成功后重启PyCharm,问题解决。
  • 问题2:
    最初想在播放器中加入“从网络下载歌曲”的功能,参考网络爬虫代码,使用requests调用相关网站接口获取下载链接。但在实际测试中,一直显示下载失败,通过其他途径如musicdl,也无法稳定使用。

1

2

  • 问题2解决方案:
    把这个功能删掉了,只保留了播放本地下载音频的功能。
  • 问题3:
    控制台输出libpng warning: iCCP: known incorrect sRGB profile。
  • 问题3解决方案:
    经AI搜索,该警告不影响程序运营,可以置之不理。
  • 问题4:
    歌曲播放时,进度条有时会突然跳回或卡顿。
  • 问题4解决方案:
    经AI优化,在更新前增加if self.player.duration() > 0:条件,只有当媒体文件有效时才设置进度条最大值和当前位置,此后问题解决。

五、其他(感悟、思考等)

(一)课程综合总结
本学期Python课程系统学习了以下内容:
1.基础语法:变量、数据类型、运算符、输入输出、代码缩进规范
2.流程控制:if-elif-else分支、for/while循环、break/continue
3.序列:列表、元组、字典、集合的增删改查及切片操作
4.字符串与正则表达式:常用方法(split、join、replace等)及简单正则匹配
5.函数:定义与调用、参数传递(位置、关键字、默认、可变)、返回值
6.面向对象:类与对象、封装、继承、多态、构造方法__init__
7.异常处理与文件操作:try-except、open/read/write、os模块
8.数据库操作:使用sqlite3进行增删改查
9.网络编程与爬虫:socket套接字通信、requests库、HTML解析基础
10.图形界面:本实验重点应用的PyQt5,包括布局、信号与槽、样式表等
(二)学习心得体会
作为一名文科生,刚开始接触Python时内心充满忐忑。但是随着课程推进,我发现Python并没有想象中那么可怕——在AI时代下,进行兴趣性的编程是非常方便的,而且Pycharm中第三方库非常丰富。此外老师从始至终一直在耐心解答、解决在实验中我们所遇到的问题,对我们有着非常大的帮助。
这次做音乐播放器,我从最初只是复制网上现成的一个小代码,功能不齐全、页面不美观、运行不流畅...然后通过和Deepseek的不断沟通修改,一步步完善代码,增添了许多功能,从100多行到了最终的340行。当看到自己设计的粉色窗口顺利播放出本地的第一首歌时,那种成就感溢于言表(有一种自己掌握高科技的感觉)。虽然中间尝试添加下载功能失败了,且无奈最终删掉这个功能,但在取舍的过程中,我也感到保证核心功能稳定可用,比贪多求全更加重要。
另外,我深刻体会到调试能力的重要性。每个报错都是一次学习的机会:通过被指出错误、搜索资料、询问AI,我逐渐学会了独立解决问题。AI可以辅助,但真正的成长需要自己动手、自己思考。
(三)意见与建议
回顾一学期的Python课程,王老师真的非常用心,课程设计对文科生也很友好。如果非要说几点建议,可能是以下这些:
1.课程内容可以稍微浅显一点:课程同时作为公选课面向全院学生,深度设置很科学,但在作为行政管理专选课时,可以考虑放弃掉后面课程中国难的内容,而拉长对基础、简单部分的讲解~
2.在每节课结束前,可以整合一下课上寻求老师帮助的同学提出的共性问题,这样也可以减少老师在课后一对一接着进行答疑解惑的时间。

!非常感谢老师一学期的辛勤付出!每次下课都答疑到很晚,对待每个问题都很认真,并且一直保持耐心、幽默风趣的为我们进行解答。线上的沟通也是一样,Python课程为我们贡献了很多梗(dong 0000000000 si、睡觉大王哈哈哈哈哈哈),最后也真诚祝愿老师身体健康,工作顺利!

posted on 2026-06-14 20:35  Flore48oz。  阅读(7)  评论(0)    收藏  举报