Python用Pyqt5制作音乐播放器

具体效果如下

需要实现的功能主要的几个有:

1、搜索结果更新至当前音乐的列表,这样播放下一首是搜素结果的下一首

2、自动播放

3、滚动音乐文本

4、音乐进度条

5、根据实际情况生成音乐列表。我这里的是下面的情况,音乐文件的格式是 

歌名_歌手.mp3

所以根据需求修改 find_mp3_files 方法,我这里返回的是

[ {"path":音乐文件路径,

"music":歌名,

"singer":歌手},

{"path":音乐文件路径,

"music":歌名,

"singer":歌手},

...]

 全部代码在此,试试吧

import fnmatch
import os
import random
import sysfrom PyQt5.QtGui import QPalette, QBrush, QPixmap
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QSlider, QLabel, \QTableWidget, QLineEdit, QTableWidgetItem
from PyQt5.QtMultimedia import QMediaPlayer, QMediaContent
from PyQt5.QtCore import QUrl, Qt, QTimerclass MusicPlayer(QMainWindow):def __init__(self):super().__init__()self.music_path = "F://wyy"  # 音乐文件夹,可以有子文件夹self.start_x = 10self.x_step = 100self.start_y = 10self.y_step = 40self.window_w, self.window_h = 500, 800self.music_list = self.find_mp3_files()self.show_list = self.music_listself.duration = 1self.position = 0self.text = "歌曲未加载"self.current_index = -1self.current_music = self.show_list[self.current_index]['music']self.current_singer = self.show_list[self.current_index]['singer']self.current_path = self.show_list[self.current_index]['path']self.status = Trueself.update_label = Trueself.init_ui()print("配置加载完成")def init_ui(self):self.setWindowTitle("音乐播放器")self.resize(self.window_w, self.window_h)self.setMinimumSize(self.window_w, self.window_h)self.setMaximumSize(self.window_w, self.window_h)palette = QPalette()  # 主界面背景palette.setBrush(QPalette.Background, QBrush(QPixmap("imgs/21.jpg")))self.setPalette(palette)self.player = QMediaPlayer()self.table_widget = QTableWidget(0, 2, parent=self)  # 检测结果列表self.table_widget.setHorizontalHeaderLabels(['歌手', '歌曲'])  # 设置列表头self.table_widget.verticalHeader().hide()  # 隐藏行索引self.table_widget.move(10, 150)self.table_widget.resize(500, 600)self.table_widget.cellClicked.connect(self.line_clicked)self.table_widget.setColumnWidth(0, 200)self.table_widget.setColumnWidth(1, 270)self.table_widget.setEditTriggers(QTableWidget.NoEditTriggers)self.table_widget.setStyleSheet("QTableWidget {background-image: url('imgs/11.jpg');}")self.load_music()self.play_button = QPushButton("播放", self)self.play_button.clicked.connect(self.play_current_music)self.play_button.move(self.start_x, self.start_y)self.change_button = QPushButton("暂停", self)self.change_button.clicked.connect(self.change_music_status)self.change_button.move(self.start_x + self.x_step, self.start_y)self.play_pre_button = QPushButton("上一首", self)self.play_pre_button.clicked.connect(self.play_pre)self.play_pre_button.move(self.start_x, self.start_y + self.y_step)self.play_next_button = QPushButton("下一首", self)self.play_next_button.clicked.connect(self.play_next)self.play_next_button.move(self.start_x + self.x_step, self.start_y + self.y_step)self.search_text = QLineEdit(self)self.search_text.resize(200, 30)self.search_text.move(self.start_x + 3 * self.x_step + 10, self.start_y)self.search_btn = QPushButton("搜索", self)self.search_btn.clicked.connect(self.search_music)self.search_btn.move(self.start_x + 2 * self.x_step + 10, self.start_y)self.music_label = QLabel(self.text, self)self.music_label.resize(self.window_w - self.start_x, 30)self.music_label.move(self.start_x, self.start_y + 2 * self.y_step)self.music_label.setAlignment(Qt.AlignCenter)self.volume_slider = QSlider(Qt.Horizontal, self)self.volume_slider.setRange(0, 100)self.volume_slider.setValue(50)self.volume_slider.setTickPosition(QSlider.TicksBelow)self.volume_slider.setTickInterval(10)self.volume_slider.resize(200, 30)self.volume_slider.valueChanged.connect(self.change_volume)self.volume_slider.move(self.start_x + 2 * self.x_step + 50, self.start_y + self.y_step + 10)self.music_pro = QLabel(self)self.music_pro_width = self.window_w - self.start_xself.music_pro.resize(self.music_pro_width, 10)self.music_pro.move(self.start_x, self.start_y + 2 * self.y_step + 40)self.music_pro.setStyleSheet("background:'#123456'")self.timer = QTimer()self.timer.timeout.connect(self.scroll_text)self.timer.start(500)self.player.stateChanged.connect(self.handle_player_status_changed)self.player.mediaStatusChanged.connect(self.handle_media_status_changed)self.player.durationChanged.connect(self.update_duration)self.player.positionChanged.connect(self.update_position)def change_music_status(self):if self.status:self.player.pause()self.status = Falseself.change_button.setText('继续')print("已暂停当前音乐", self.current_music)else:self.status = Trueself.player.play()self.change_button.setText('暂停')print("已继续当前音乐", self.current_music)def handle_media_status_changed(self, status):if status == QMediaPlayer.EndOfMedia:self.play_next()def handle_player_status_changed(self, state):if state == QMediaPlayer.PlayingState:self.update_label = Trueelif state == QMediaPlayer.StoppedState:self.update_label = Falsedef search_music(self):text = self.search_text.text()if text:self.show_list = []for i in self.music_list:for j in i.values():if text in j:self.show_list.append(i)breakself.load_music()print("查询结束")else:self.music_list = self.find_mp3_files()  # 从本地重新加载self.show_list = self.music_list self.load_music()print('>>>>>>>>>>>>>>>未查询到相关音乐,已重新加载列表')def clear_table(self):self.table_widget.clearContents()self.table_widget.setHorizontalHeaderLabels(['歌手', '歌曲'])  # 设置列表头self.table_widget.setRowCount(0)print("已更新列表")def line_clicked(self, row, column):self.current_index = rowself.update_current_music()print("点击了", self.current_music, self.current_singer)def load_music(self):self.clear_table()n = 0for i in self.show_list:self.table_widget.setRowCount(n + 1)self.table_widget.setItem(n, 0, QTableWidgetItem(i['singer']))self.table_widget.setItem(n, 1, QTableWidgetItem(i['music']))n += 1print('已重新加载音乐列表')def play_current_music(self):if self.current_index == -1:self.current_index = 0self.update_current_music()print(self.current_index)self.play_music()def play_music(self):self.player.setMedia(QMediaContent(QUrl.fromLocalFile(self.current_path)))self.player.play()self.text = f"当前播放: {self.current_music} —— {self.current_singer} "self.music_label.setText(self.text)print("正在播放:", self.current_music)def update_current_music(self):self.current_path = self.show_list[self.current_index]['path']self.current_singer = self.show_list[self.current_index]['singer']self.current_music = self.show_list[self.current_index]['music']print("已更新当前音乐")def play_pre(self):print("播放上一首")for i, j in enumerate(self.show_list):if self.current_path == j['path']:if i != 0:self.current_index = i - 1else:self.current_index = -1breakself.update_current_music()print("切换音乐为", self.current_music)self.play_music()def play_next(self):print("播放下一首")for i, j in enumerate(self.show_list):if self.current_path == j['path']:if i != len(self.show_list) - 1:self.current_index = i + 1else:self.current_index = 0breakself.update_current_music()print("切换音乐为", self.current_music)self.play_music()def change_volume(self, value):self.player.setVolume(value)print("设置音量为", value)def set_position(self):self.music_pro.resize(int(self.position / self.duration * self.music_pro_width), 10)c = int(self.position / self.duration * 255)h = self.rgb2hex(c, c, c)self.music_pro.setStyleSheet(f"background:'{h}'")def update_duration(self, duration):if not self.update_label:returnself.duration = durationdef update_position(self, position):if not self.update_label:returnself.position = positionself.set_position()def scroll_text(self):current_text = self.music_label.text()scroll_text = current_text[1:] + current_text[0]self.music_label.setText(scroll_text)self.music_label.setStyleSheet(f"color:{self.rgb2hex(*self.random_color())}")def rgb2hex(self, r, g, b):return "#{:02x}{:02x}{:02x}".format(r, g, b)def find_mp3_files(self):  # 生成音乐文件列表,根据需求自定义mp3_files = []for root, dirs, files in os.walk(self.music_path):for file in files:if fnmatch.fnmatch(file, '*.mp3'):if '_' in file:r = {'music': file.split('_')[0],'singer': file.split('_')[1].split('.')[0],'path': os.path.join(root, file)}mp3_files.append(r)return mp3_filesdef random_color(self):  # 随机颜色r, g, b = random.randint(0, 256), random.randint(0, 256), random.randint(0, 256)return r, g, bif __name__ == "__main__":app = QApplication(sys.argv)player = MusicPlayer()player.show()sys.exit(app.exec_())

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/3245885.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

【Chatgpt大语言模型医学领域中如何应用】

随着人工智能技术 AI 的不断发展和应用,ChatGPT 作为一种强大的自然语言处理技术,无论是 自然语言处理、对话系统、机器翻译、内容生成、图像生成,还是语音识别、计算机视觉等方面,ChatGPT 都有着广泛的应用前景。特别在临床医学领…

PHP短视频去水印+影视小程序微信去水印小程序自主开发对接流量主

短视频去水印影视小程序新商机:微信去水印小程序对接流量主全攻略💼 🎬【短视频去水印,内容创作新助力】 在短视频风靡的今天,每一个创意都值得被完整呈现。但恼人的水印常常破坏了这份完美。现在,有了专…

【机器学习】分类算法-支持向量机

一、前言 前面讲了KNN算法,这里我们来学习一下支持向量机的模型使用,看一下用支持向量机的方法,是否可以完成了之前KNN算法中的那个“约会网站配对”的算法实现嘞。 二、什么为支持向量机 我们跟着老师的要求来,从四个层次来理解…

Nuxt.js头部魔法:轻松自定义页面元信息,提升用户体验

title: Nuxt.js头部魔法:轻松自定义页面元信息,提升用户体验 date: 2024/7/16 updated: 2024/7/16 author: cmdragon excerpt: 摘要:“Nuxt.js头部魔法:轻松自定义页面元信息,提升用户体验”介绍如何使用useHead函数…

PostgreSQL使用(三)

说明:本文介绍PostgreSQL的数据类型和运算符; 数据类型 常用的数据类型如下: 运算符 如下: 运算符的优先级如下: 不需要强记硬背,只需要记住括号可以提高运算符的优先级即可; 总结 本文介绍…

从数据湖到湖仓一体:统一数据架构演进之路

文章目录 一、前言二、什么是湖仓一体?起源概述 三、为什么要构建湖仓一体?1. 成本角度2. 技术角度 四、湖仓一体实践过程阶段一:摸索阶段(仓、湖并行建设)阶段二:发展阶段方式一、湖上建仓(湖在下、仓在上)方式二:仓外…

SQL GROUPING运算符详解

在大数据开发中,我们经常需要对数据进行分组和汇总分析。 目录 1. GROUPING运算符概念2. 语法和用法3. 实际应用示例4. GROUPING运算符的优势5. 高级应用场景5.1 与CASE语句结合使用5.2 多维数据分析 6. 性能考虑和优化技巧7. GROUPING运算符的局限性8. 最佳实践9. GROUPING与其…

AI聊天可能涉黄?用户该如何对待AI聊天

AI伴侣是生成式大模型发展的产物,它是一个聊天机器人,能够随叫随到,提供情绪价值,还能发腿照和腹肌照。它可以是对现实或小说中某个人物的角色扮演,也可以是凭空创造出来的一个形象,总之不是真人。但因为接…

防火墙--双机热备

目录 双击热备作用 防火墙和路由器备份不同之处 如何连线 双机 热备 冷备 VRRP VGMP(华为私有协议) 场景解释 VGMP作用过程 主备的形成场景 接口故障的切换场景 整机故障 原主设备故障恢复的场景 如果没有开启抢占 如果开启了抢占 负载分…

mac如何合并pdf文件到一个文件 macpdf合并 Mac如何合并pdf文件

在数字化的今天,pdf文件因其跨平台、格式统一等优势,已经成为工作、学习和生活中不可或缺的文件格式。然而,当我们需要合并多个pdf文件时,可能会感到有些无从下手。本文将为你详细介绍几种简单实用的合并pdf的方法,让你…

ArkUI组件——循环控制/List

循环控制 class Item{name: stringprice:number}private items:Array<Item> [new Item("A0",2399),new Item("BE",1999),new Item("Ro",2799)] ForEach(this.items,(item:Item) > {})List组件 列表List是一种复杂的容器&#xff0c;…

安全防御---防火墙双击热备与带宽管理

目录 一、实验拓扑 二、实验需求 三、实验的大致思路 四、实验过程 4、基础配置 4.1 FW4的接口信息 4.2 新建办公&#xff0c;生产&#xff0c;游客&#xff0c;电信&#xff0c;移动安全区域 4.3 接口的网络配置 生产区:10.0.1.2/24 办公区:10.0.2.2/24 4.4 FW4的…

只需要3个方法,实现硬盘格式化恢复

人有失手马有失蹄&#xff0c;我们在日常的电脑办公生活中总会出现各种各样的疏忽&#xff0c;如硬盘格式化。许多人因此丢失了重要的文件数据。硬盘格式化&#xff0c;令大家闻风丧胆&#xff0c;认为设备格式化后数据便不复存在&#xff0c;只得在悔恨中自行把丢失的文件一个…

cesium 实现地图环境功能 - 雨,雪,雾特效

需求背景解决效果Codeindex.vuefogEffect.tsrain.glslsnow.glslfog.glsl 需求背景 需要实现天气模拟&#xff0c;日照模拟功能&#xff0c;提高三维实景效果 解决效果 Code 注意&#xff1a;我以下glsl文件时基于 webgl1.0&#xff0c;即cesium&#xff0c;创建球的时候&…

逆向案例二十二——请求头参数加密,某省公共资源交易电子公共服务平台

网址&#xff1a;交易列表 - 福建省公共资源交易电子公共服务平台 想要抓取数据&#xff0c;进行抓包分析&#xff0c;找到数据包&#xff0c;发现请求头有加密参数Portal-Sign&#xff0c;返回的数据内容也进行了加密。 直接搜索加密参数&#xff0c;找到加密位置&#xff0c…

Julia 初学者指南(二) | 数据类型与函数基础

唠唠闲话 Julia 是一种高性能的动态编程语言&#xff0c;特别适用于数值分析和计算科学领域。它拥有一个强大的类型系统和灵活的多重分派机制&#xff0c;这使得代码易于编写同时还能保持接近 C 语言的运行速度。此外&#xff0c;Julia 也能无缝调用 C 和 Fortran 库&#xff0…

Linux网络编程-socket套接字使用详解

1.概念 在Linux中&#xff0c;套接字&#xff08;socket&#xff09;是一种通信机制&#xff0c;用于实现不同进程之间或同一主机上的不同线程之间的数据交换。它是网络编程的基础&#xff0c;允许应用程序通过网络进行通信&#xff0c;也可以在同一台机器上的不同进程间进行通…

【STM32】MPU内存保护单元

注&#xff1a;仅在F7和M7系列上使用介绍 功能&#xff1a; 设置不同存储区域的存储器访问权限&#xff08;管理员、用户&#xff09; 设置存储器&#xff08;内存和外设&#xff09;属性&#xff08;可缓冲、可缓存、可共享&#xff09; 优点&#xff1a;提高嵌入式系统的健壮…

如何将电子书发送到kindle

修改guide Amazon之kindle 修改邮箱 参考&#xff1a; blog 多种方式&#xff1a;如何将电子书发送到kindle

《知识点扫盲 · 学会 WebSocket》

&#x1f4e2; 大家好&#xff0c;我是 【战神刘玉栋】&#xff0c;有10多年的研发经验&#xff0c;致力于前后端技术栈的知识沉淀和传播。 &#x1f497; &#x1f33b; CSDN入驻不久&#xff0c;希望大家多多支持&#xff0c;后续会继续提升文章质量&#xff0c;绝不滥竽充数…