pyqt5+pygame实现音乐播放器,可以自动提取文件图片,最终版本

pyqt5+pyagme实现音乐播放器,运用了pyqt5的list,可以双击播放,会自动提取音频文件的图片

源码下载**:自己往下翻**!!!,(但如果你想用积分下载我也拦不了你)
https://download.csdn.net/download/oys19812007/18974107?spm=1001.2014.3001.5501
之前没事干,看windows10自带的播放器有一(亿)点点不顺眼,然后想写一个播放器,
正好有学了点pyqt5,然后就整了这个东西,耗时4天,差不多也算是最终版本了吧,
如果接下来有时间的话也会继续更新下去,
但至少也要过多一年了,毕竟也快初三了,要认真复习了

( •̀ ω •́ )✧
python实现的音乐播放器,成品如下:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210522195042731.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L295czE5ODEyMDA3,size_16,color_FFFFFF,t_70

要用到的库

import sys
import re
import pygame

from mutagen import File
import time
import os, math
from PIL import Image, ImageDraw, ImageFilter
# import requests
# import jsonpath
# from mutagen.mp3 import MP3
# from mutagen import File
# from urllib.request import urlretrieve
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QFileDialog, QMessageBox, QListWidget, QLabel, QListWidgetItem, QApplication, QWidget
from PyQt5.QtCore import QTimer, QDateTime, Qt
from PyQt5.QtGui import QIcon, QPixmap, QColor, QPainter, QPixmap
from PyQt5 import QtMultimedia, QtWidgets, QtCore
from PyQt5.QtGui import QFont, QCursor
import qtawesome
import threading
import random
import requests

在这里插入图片描述

下面是功能代码的分享

这里是item双击播放的源码,item绑定这个后可以调用pyagme播放

'''这里是item双击播放的源码,item绑定这个后可以调用pyagme播放
'''
    def change_func(self, listwidget):
            global num
            item = QListWidgetItem(self.listwidget.currentItem())
            print (item.text())
            #print (item.flags())
            num = int(listwidget.currentRow())
            a,f = os.path.split(SongPath[num])#分割文件名  
            f,ex = os.path.splitext(f)
            #self.label.setText(wenjianming)#设置标签的文本为音乐的名字    
            self.label1.setText(f)
            print (listwidget.currentRow())
            self.bofang(num)

    def bofang(self, num):
        try:
            global pause
            self.photo(num)
            self.console_button_3.setIcon(qtawesome.icon('fa.pause', color='#F76677', font=18))
            pause = False
            # QMessageBox.information(self, "ListWidget", "你选择了: "+item.text())# 显示出消息提示框
            fill = SongPath[num]
            print(fill)
            try:
                pygame.mixer.stop()
            except:
                pass
            pygame.mixer.init()
            try:
                self.Timer = QTimer()
                self.Timer.start(500)
            except:
                pass
            pygame.mixer.music.load(SongPath[num])  # 载入音乐
            pygame.mixer.music.play()  # 播放音乐


        except:
            time.sleep(0.1)
            print ('system error')
            self.next()
            pass

接下来是开始的代码块

    def start(self):
        try:
            global SongPath
            global num
            global filew
            global asas
            if not os.path.exists("2.png"):
                try:
                    req = requests.get('https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fy.gtimg.cn%2Fmusic%2Fphoto_new%2FT001R300x300M000002ztBMe06cOx0.jpg%3Fmax_age%3D2592000&refer=http%3A%2F%2Fy.gtimg.cn&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1625464213&t=a30c07bda8c2ab7d8001a59353e936e0')

                    checkfile  = open('ls2.png','w+b')
                    for i in req.iter_content(100000):
                        checkfile.write(i)

                    checkfile.close()
                    lsfile = './ls2.png'
                    safile = './2.png'
                    draw(lsfile,safile)
                except:
                    print ('download error')
                    pass
            fileN = QtWidgets.QFileDialog.getExistingDirectory(None, "选取文件夹", "")

            filew = fileN + '/'
            asas = filew
            l1 = [name for name in os.listdir(fileN) if name.endswith('.mp3')]
            l2 = [name for name in os.listdir(fileN) if name.endswith('.flac')]
            l3 = [name for name in os.listdir(fileN) if name.endswith('wma')]
            SongName = l1 + l2 + l3
            SongPath = [filew + i for i in SongName]
            print(SongPath)
            pygame.mixer.init()
            self.Timer = QTimer()
            self.Timer.start(500)
            # self.Timer.timeout.connect(self.timercontorl)#时间函数,与下面的进度条和时间显示有关
            # self.label = os.path.splitext(SongName[num])#分割文件名和扩展名
            # self.label.setText(wenjianming)#设置标签的文本为音乐的名字
            print(SongPath[num])
            self.photo(num)
            a, f = os.path.split(SongPath[num])  # 分割文件名
            f, ex = os.path.splitext(f)
            # self.label.setText(wenjianming)#设置标签的文本为音乐的名字
            self.label.setText(f)
            pygame.mixer.music.load(SongPath[num])  # 载入音乐
            pygame.mixer.music.play()  # 播放音乐2
            self.label3.setText(str(pygame.mixer.music.get_volume()))
            r = 0
            for i in SongName:
                # self.listwidget.addItem(i)#将文件名添加到listWidget

                self.listwidget.addItem(i)
                self.listwidget.item(r).setForeground(QtCore.Qt.white)
                r = r + 1
            # self.next(self)
        except:
            return

下面是音量加和音量减
在这里插入图片描述

    def voiceup(self): 
        print ('up')
        global voice
        voice+=0.1
        if voice>1:
            voice=1
        pygame.mixer.music.set_volume(voice)

    def voicedown(self):
        print ('down')
        global voice
        voice-=0.1
        if voice<0:
            voice=0
        pygame.mixer.music.set_volume(voice)    

这个是播放和暂停

    def pause(self):
        global pause
        if pause:
            try:
              pygame.mixer.music.unpause()
            except:
                pass
            self.console_button_3.setIcon(qtawesome.icon('fa.pause', color='#3FC89C', font=18))
            pause = False
        else:
            try:
              pygame.mixer.music.pause()
            except:
                pass
            self.console_button_3.setIcon(qtawesome.icon('fa.play', color='#F76677', font=18))
            pause = True

下面的添加目录:
在这里插入图片描述

    def add(self):
        try:

            
            global SongPath
            global num
            global filew
            global asas
            num = 0
            fileN = QtWidgets.QFileDialog.getExistingDirectory(None,"选取文件夹","")
            self.listwidget.clear()
            filew = fileN +'/'
            asas = filew
            l1 = [name for name in os.listdir(fileN)if name.endswith('.mp3')]
            l2 = [name for name in os.listdir(fileN)if name.endswith('.flac')]
            l3 = [name for name in os.listdir(fileN)if name.endswith('wma')]
            SongName = l1 +l2+l3
            SongPath =[filew +i for i in SongName]
            print (SongPath)   
            #self.Timer.timeout.connect(self.timercontorl)#时间函数,与下面的进度条和时间显示有关
            #self.label = os.path.splitext(SongName[num])#分割文件名和扩展名   
            #self.label.setText(wenjianming)#设置标签的文本为音乐的名字    
            print (SongPath[num])  
            r = 0
            for i in SongName:
                #self.listwidget.addItem(i)#将文件名添加到listWidget

                self.listwidget.addItem(i)
                self.listwidget.item(r).setForeground(QtCore.Qt.white)
                r = r +1
            #self.next(self)
        except:
             filew = asas

让pyqt5界面移动的代码块**

    def mousePressEvent(self, event):
        #if event.button()==QtWidgets.QPushButton:
            self.m_flag=True
            self.m_Position=event.globalPos()-self.pos() #获取鼠标相对窗口的位置
            event.accept()
            #self.setCursor(QCursor(Qt.OpenHandCursor))  #更改鼠标图标
            
    def mouseMoveEvent(self, QMouseEvent):
        #if QtWidgets.QPushButton and self.m_flag:  
            self.move(QMouseEvent.globalPos()-self.m_Position)#更改窗口位置
            QMouseEvent.accept()
            
    def mouseReleaseEvent(self, QMouseEvent):
        self.m_flag=False
        #self.setCursor(QCursor(Qt.ArrowCursor))

上面item绑定的是双击版本的,此外我还写了单击的版本,如下:
在这里插入图片描述

    def clicked(self,item):

                global pause
                print(str(item.text()))
                self.console_button_3.setIcon(qtawesome.icon('fa.pause', color='#F76677', font=18))
                pause = False
                #QMessageBox.information(self, "ListWidget", "你选择了: "+item.text())# 显示出消息提示框
                fill = filew +item.text()
                print (fill)
                pygame.mixer.stop()
                pygame.mixer.init()
                self.Timer=QTimer()    
                self.Timer.start(500)        
                pygame.mixer.music.load(fill)#载入音乐
                pygame.mixer.music.play()#播放音乐

由于这个还只是刚开始的版本,以后还会继续更新,目前版本的bug已被修复

2021/6/21

添加了提取音频文件的功能,效果图如下

在这里插入图片描述
上面的图片是经过画圆处理的,从文件提取出来的代码如下

    def photo(self,num):
        try:
            audio = File(SongPath[num])
            mArtwork = audio.tags['APIC:'].data
            with open('ls.png', 'wb') as img:
                img.write(mArtwork)
            try:
                lsfile = './ls.png'
                safile = './1.png'
                draw(lsfile,safile)

                pix_img = QtGui.QPixmap('./1.png')
                pix = pix_img.scaled(300, 300, QtCore.Qt.KeepAspectRatio)
                self.label5.setPixmap(pix)
            except:
                print ('do error')
                pix_img = QtGui.QPixmap('./ls.png')
                pix = pix_img.scaled(300, 300, QtCore.Qt.KeepAspectRatio)
                self.label5.setPixmap(pix)
        except:
            print('no picture')
            if  os.path.exists("2.png"):
                pix_img = QtGui.QPixmap('./2.png')
                pix = pix_img.scaled(300, 300, QtCore.Qt.KeepAspectRatio)
                self.label5.setPixmap(pix)
            else:
                try:
                    req = requests.get('https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fy.gtimg.cn%2Fmusic%2Fphoto_new%2FT001R300x300M000002ztBMe06cOx0.jpg%3Fmax_age%3D2592000&refer=http%3A%2F%2Fy.gtimg.cn&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1625464213&t=a30c07bda8c2ab7d8001a59353e936e0')

                    checkfile  = open('ls2.png','w+b')
                    for i in req.iter_content(100000):
                        checkfile.write(i)

                    checkfile.close()
                    lsfile = './ls2.png'
                    safile = './2.png'
                    draw(lsfile,safile)
                except:
                    print ('download error')
                    pix_img = QtGui.QPixmap('./2.png')
                    pix = pix_img.scaled(300, 300, QtCore.Qt.KeepAspectRatio)
                    self.label5.setPixmap(pix)
                    pass
                pass

下面的是画圆的代码

def crop_max_square(pil_img):
    return crop_center(pil_img, min(pil_img.size), min(pil_img.size))


def crop_center(pil_img, crop_width, crop_height):
    img_width, img_height = pil_img.size
    return pil_img.crop(((img_width - crop_width) // 2,
                         (img_height - crop_height) // 2,
                         (img_width + crop_width) // 2,
                         (img_height + crop_height) // 2))

def mask_circle_transparent(pil_img, blur_radius, offset=0):
    offset = blur_radius * 2 + offset
    mask = Image.new("L", pil_img.size, 0)
    draw = ImageDraw.Draw(mask)
    draw.ellipse((offset, offset, pil_img.size[0] - offset, pil_img.size[1] - offset), fill=255)
    mask = mask.filter(ImageFilter.GaussianBlur(blur_radius))

    result = pil_img.copy()
    result.putalpha(mask)
    return result

def draw(lsfile,safile):
    markImg = Image.open(lsfile)
    thumb_width = 600

    im_square = crop_max_square(markImg).resize((thumb_width, thumb_width), Image.LANCZOS)
    im_thumb = mask_circle_transparent(im_square, 0)
    im_thumb.save(safile)
    os.remove(lsfile)

全部代码如下

# coding:utf-8

# from PyQt5 import QtCore,QtGui,QtWidgets
import sys
import re
import pygame

from mutagen import File
import time
import os, math
from PIL import Image, ImageDraw, ImageFilter
# import requests
# import jsonpath
# from mutagen.mp3 import MP3
# from mutagen import File
# from urllib.request import urlretrieve
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QFileDialog, QMessageBox, QListWidget, QLabel, QListWidgetItem, QApplication, QWidget
from PyQt5.QtCore import QTimer, QDateTime, Qt
from PyQt5.QtGui import QIcon, QPixmap, QColor, QPainter, QPixmap
from PyQt5 import QtMultimedia, QtWidgets, QtCore
from PyQt5.QtGui import QFont, QCursor
import qtawesome
import threading
import random
import requests

play = 'shun'
stop = False
SongPath = []
filew = 1
num = 0
voice = 0.5
pause = False
asas = 1
big = False


class MainUi(QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()
        self.init_ui()
        #self.start()

        try:
            icon_path = os.path.join(os.path.dirname(__file__), './logo.ico')

            icon = QIcon()
            icon.addPixmap(QPixmap(icon_path))  # 这是对的。
            self.setWindowIcon(icon)
        except:
            pass
        t1 = threading.Thread(target=self.action)
        t1.setDaemon(True)
        t1.start()

    def init_ui(self):
        self.setFixedSize(960, 700)
        self.main_widget = QtWidgets.QWidget()  # 创建窗口主部件
        self.main_layout = QtWidgets.QGridLayout()  # 创建主部件的网格布局
        self.main_widget.setLayout(self.main_layout)  # 设置窗口主部件布局为网格布局

        self.close_widget = QtWidgets.QWidget()  # 创建关闭侧部件
        self.close_widget.setObjectName('close_widget')
        self.close_layout = QtWidgets.QGridLayout()  # 创建左侧部件的网格布局层
        self.close_widget.setLayout(self.close_layout)  # 设置左侧部件布局为网格

        self.left_widget = QtWidgets.QWidget()  # 创建左边侧部件
        self.left_widget.setObjectName('left_widget')
        self.left_layout = QtWidgets.QGridLayout()  # 创建左侧部件的网格布局层
        self.left_widget.setLayout(self.left_layout)  # 设置左侧部件布局为网格

        self.right_widget = QtWidgets.QWidget()  # 创建右侧部件
        self.right_widget.setObjectName('right_widget')
        self.right_layout = QtWidgets.QGridLayout()
        self.right_widget.setLayout(self.right_layout)  # 设置右侧部件布局为网格

        self.down_widget = QtWidgets.QWidget()  # 创建下面部件
        self.down_widget.setObjectName('down_widget')
        self.down_layout = QtWidgets.QGridLayout()
        self.down_widget.setLayout(self.down_layout)  # 设置下侧部件布局为网格

        self.label = QLabel(self)
        self.label.setText("first line")
        self.label.setStyleSheet("color:white")
        self.label.setMaximumSize(310, 20)

        self.main_layout.addWidget(self.right_widget, 0, 20, 90, 90)  # 22右侧部件在第0行第3列,占8行9列
        self.down_layout.addWidget(self.label, 1, 0, 1, 1)
        self.main_layout.addWidget(self.left_widget, 0, 0, 90, 20)
        self.main_layout.addWidget(self.down_widget, 100, 0, 10, 110)
        self.main_layout.addWidget(self.close_widget, 0, 107, 1, 3)  # 左侧部件在第0行第0列,占1行3列
        self.setCentralWidget(self.main_widget)  # 设置窗口主部件


        self.listwidget = QListWidget(self)
        self.listwidget.doubleClicked.connect(lambda: self.change_func(self.listwidget))
        self.right_layout.addWidget(self.listwidget, 3, 0, 100, 90)
        self.listwidget.setStyleSheet('''background-color:transparent''')

        self.left_close = QtWidgets.QPushButton("")  # 关闭按钮
        self.left_close.clicked.connect(self.close)
        self.left_visit = QtWidgets.QPushButton("")  # 空白按钮
        self.left_visit.clicked.connect(self.big)
        self.left_mini = QtWidgets.QPushButton("")  # 最小化按钮
        self.left_mini.clicked.connect(self.mini)
        self.close_layout.addWidget(self.left_mini, 0, 0, 1, 1)
        self.close_layout.addWidget(self.left_close, 0, 2, 1, 1)
        self.close_layout.addWidget(self.left_visit, 0, 1, 1, 1)
        self.left_close.setFixedSize(15, 15)  # 设置关闭按钮的大小
        self.left_visit.setFixedSize(15, 15)  # 设置按钮大小
        self.left_mini.setFixedSize(15, 15)  # 设置最小化按钮大小
        self.left_close.setStyleSheet(
            '''QPushButton{background:#F76677;border-radius:5px;}QPushButton:hover{background:red;}''')
        self.left_visit.setStyleSheet(
            '''QPushButton{background:#F7D674;border-radius:5px;}QPushButton:hover{background:yellow;}''')
        self.left_mini.setStyleSheet(
            '''QPushButton{background:#6DDF6D;border-radius:5px;}QPushButton:hover{background:green;}''')

        self.left_add = QtWidgets.QPushButton("添加")  # 添加按钮
        self.left_layout.addWidget(self.left_add, 0, 0, 2, 2)
        self.left_add.setStyleSheet(
            '''QPushButton{background:#F76677;border-radius:5px;}QPushButton:hover{background:red;}''')
        self.left_add.clicked.connect(self.add)



        self.label2 = QLabel(self)
        self.label2.setText("当前为顺序播放")
        self.label2.setStyleSheet("color:#6DDF6D")
        self.left_layout.addWidget(self.label2, 4, 0, 2, 2)

        self.label3 = QLabel(self)
        self.label3.setText("")
        self.label3.setStyleSheet("color:white")
        self.down_layout.addWidget(self.label3, 1, 3, 1, 1)

        self.label7 = QLabel(self)
        self.label7.setText("")
        self.label7.setStyleSheet("color:white")


        '''
        self.label1 = QLabel(self)
        self.label1.setText("first line")
        self.label1.setStyleSheet("color:white")
        '''

        self.label5 = QLabel(self)
        #self.label5.setScaledContents(True)
        pix_img = QtGui.QPixmap('./2.png')
        pix = pix_img.scaled(300, 300, QtCore.Qt.KeepAspectRatio)
        self.label5.setPixmap(pix)
        #self.label5.setMaximumSize(1,1)
        self.left_layout.addWidget(self.label5,2,0,2,2)

        self.label6 = QLabel(self)
        self.label6.setText("")
        self.label6.setStyleSheet("color:#6DDF6D")
        self.left_layout.addWidget(self.label6, 2, 0, 2, 2)



        self.right_process_bar = QtWidgets.QProgressBar()  # 播放进度部件
        self.right_process_bar.setValue(49)
        self.right_process_bar.setFixedHeight(3)  # 设置进度条高度
        self.right_process_bar.setTextVisible(False)  # 不显示进度条文字

        self.right_playconsole_widget = QtWidgets.QWidget()  # 播放控制部件
        self.right_playconsole_layout = QtWidgets.QGridLayout()  # 播放控制部件网格布局层
        self.right_playconsole_widget.setLayout(self.right_playconsole_layout)

        self.console_button_1 = QtWidgets.QPushButton(qtawesome.icon('fa.backward', color='#3FC89C'), "")
        self.console_button_1.clicked.connect(self.last)
        self.console_button_1.setStyleSheet(
            '''QPushButton{background:#172940;border-radius:5px;}QPushButton:hover{background:#3684C8;}''')

        self.console_button_2 = QtWidgets.QPushButton(qtawesome.icon('fa.forward', color='#3FC89C'), "")
        self.console_button_2.clicked.connect(self.nextion)
        self.console_button_2.setStyleSheet(
            '''QPushButton{background:#172940;border-radius:5px;}QPushButton:hover{background:#3684C8;}''')

        self.console_button_3 = QtWidgets.QPushButton(qtawesome.icon('fa.pause', color='#3FC89C', font=18), "")
        self.console_button_3.clicked.connect(self.pause)
        self.console_button_3.setStyleSheet(
            '''QPushButton{background:#172940;border-radius:5px;}QPushButton:hover{background:#3684C8;}''')

        self.console_button_4 = QtWidgets.QPushButton(qtawesome.icon('fa.volume-down', color='#3FC89C', font=18), "")
        self.console_button_4.clicked.connect(self.voicedown)
        self.console_button_4.setStyleSheet(
            '''QPushButton{background:#172940;border-radius:5px;}QPushButton:hover{background:#3684C8;}''')

        self.console_button_5 = QtWidgets.QPushButton(qtawesome.icon('fa.volume-up', color='#3FC89C', font=18), "")
        self.console_button_5.clicked.connect(self.voiceup)
        self.console_button_5.setStyleSheet(
            '''QPushButton{background:#172940;border-radius:5px;}QPushButton:hover{background:#3684C8;}''')

        self.console_button_6 = QtWidgets.QPushButton(qtawesome.icon('fa.align-center', color='#3FC89C', font=18), "")
        self.console_button_6.clicked.connect(self.playmode)
        self.console_button_6.setStyleSheet(
            '''QPushButton{background:#172940;border-radius:5px;}QPushButton:hover{background:#3684C8;}''')

        self.console_button_3.setIconSize(QtCore.QSize(30, 30))

        self.right_playconsole_layout.addWidget(self.console_button_1, 0, 1)
        self.right_playconsole_layout.addWidget(self.console_button_2, 0, 3)
        self.right_playconsole_layout.addWidget(self.console_button_3, 0, 2)
        self.right_playconsole_layout.addWidget(self.console_button_4, 0, 0)
        self.right_playconsole_layout.addWidget(self.console_button_5, 0, 4)
        self.right_playconsole_layout.addWidget(self.console_button_6, 0, 5)
        self.right_playconsole_layout.setAlignment(QtCore.Qt.AlignCenter)  # 设置布局内部件居中显示

        self.down_layout.addWidget(self.right_process_bar, 0, 0, 1, 4)  # 第0行第0列,占8行3列
        # 第0行第0列,占8行3列

        self.down_layout.addWidget(self.label7, 1, 2, 1, 1)

        #self.down_layout.addWidget(self.label1, 1, 0, 1, 2)
        self.down_layout.addWidget(self.right_playconsole_widget, 1, 0, 1, 4)
        self.right_process_bar.setStyleSheet('''
            QProgressBar::chunk {
                background-color: #F76677;
            }
        ''')

        self.right_playconsole_widget.setStyleSheet('''
            QPushButton{
                border:none;
            }
        ''')

        self.left_widget.setStyleSheet('''
             QPushButton{border:none;color:white;}
             QPushButton#left_label{
             border:none;
             border-bottom:1px solid white;
             font-size:18px;
             font-weight:700;
             font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
             }
             QPushButton#left_button:hover{border-left:4px solid red;font-weight:700;}
             QWidget#left_widget{
             background:#2B2B2B;
             border-top:1px solid white;
             border-bottom:1px solid white;
             border-left:1px solid white;
             border-top-left-radius:10px;
             border-bottom-left-radius:10px;
             }
             ''')

        self.close_widget.setStyleSheet('''
             QPushButton{border:none;color:white;}
             QPushButton#close_label{
             border:none;
             border-bottom:1px solid white;
             font-size:18px;
             font-weight:700;
             font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
             }
             QPushButton#close_button:hover{border-left:4px solid red;font-weight:700;}
             QWidget#close_widget{
             background:#232C51;
             border-top:1px solid white;
             border-bottom:1px solid white;
             border-left:1px solid white;
             border-top-left-radius:10px;
             border-bottom-left-radius:10px;
             border-top-right-radius:10px;
             border-bottom-right-radius:10px;
             }
             ''')
        self.right_widget.setStyleSheet('''
        QWidget#right_widget{
        color:#232C51;
        background:#191618;
        border-top:1px solid darkGray;
        border-bottom:1px solid darkGray;
        border-right:1px solid darkGray;
        border-top-right-radius:10px;
        border-bottom-right-radius:10px;
        }
        QLabel#right_lable{
        border:none;
        font-size:16px;
        font-weight:700;
        font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
        }
        ''')

        self.down_widget.setStyleSheet('''
        QWidget#down_widget{
        color:#172940;
        background:#172940;
        border-top:1px solid darkGray;
        border-bottom:1px solid darkGray;
        border-right:1px solid darkGray;
        border-top-right-radius:10px;
        border-bottom-right-radius:10px;
        border-top-left-radius:10px;
        border-bottom-left-radius:10px;
        }
        QLabel#down_lable{
        border:none;
        font-size:16px;
        font-weight:700;
        font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
        }
        ''')
        self.setWindowOpacity(0.9)  # 设置窗口透明度
        self.setAttribute(QtCore.Qt.WA_TranslucentBackground)
        self.setWindowFlag(QtCore.Qt.FramelessWindowHint)  # 隐藏边框
        self.main_layout.setSpacing(0)

    # 以下为窗口控制代码



    def big(self):
        global big
        print (big)
        if not big:
            self.setWindowState(Qt.WindowMaximized)
            big = True
        elif big:
            self.setWindowState(Qt.WindowNoState)
            big = False
        # print (windowState())

    def close(self):
        reply = QtWidgets.QMessageBox.question(self, u'警告', u'确定退出?', QtWidgets.QMessageBox.Yes,
                                               QtWidgets.QMessageBox.No)
        if reply == QtWidgets.QMessageBox.Yes:
            close = True
            try:
                pygame.mixer.music.stop()
            except:
                pass

            sys.exit()

        else:
            pass

    def mini(self):

        self.showMinimized()

    def mousePressEvent(self, event):
        global big
        big = False
        self.setWindowState(Qt.WindowNoState)
        # if event.button()==QtWidgets.QPushButton:
        self.m_flag = True
        self.m_Position = event.globalPos() - self.pos()  # 获取鼠标相对窗口的位置
        event.accept()


    def mouseMoveEvent(self, QMouseEvent):
        global big
        big = False
        self.setWindowState(Qt.WindowNoState)
        # if QtWidgets.QPushButton and self.m_flag:
        self.move(QMouseEvent.globalPos() - self.m_Position)  # 更改窗口位置
        QMouseEvent.accept()

    def mouseReleaseEvent(self, QMouseEvent):
        global big
        big = False
        self.setWindowState(Qt.WindowNoState)
        self.m_flag = False

    def closeEvent(self, event):
        reply = QtWidgets.QMessageBox.question(self, u'警告', u'是否退出?', QtWidgets.QMessageBox.Yes,
                                               QtWidgets.QMessageBox.No)
        if reply == QtWidgets.QMessageBox.Yes:
            sys.exit()


        else:
            event.ignore()

    # 以下为功能代码

    def dis(self):
        pass



    def photo(self,num):
        try:
            audio = File(SongPath[num])
            mArtwork = audio.tags['APIC:'].data
            with open('ls.png', 'wb') as img:
                img.write(mArtwork)
            try:
                lsfile = './ls.png'
                safile = './1.png'
                draw(lsfile,safile)

                pix_img = QtGui.QPixmap('./1.png')
                pix = pix_img.scaled(300, 300, QtCore.Qt.KeepAspectRatio)
                self.label5.setPixmap(pix)
            except:
                print ('do error')
                pix_img = QtGui.QPixmap('./ls.png')
                pix = pix_img.scaled(300, 300, QtCore.Qt.KeepAspectRatio)
                self.label5.setPixmap(pix)
        except:
            print('no picture')
            if  os.path.exists("2.png"):
                pix_img = QtGui.QPixmap('./2.png')
                pix = pix_img.scaled(300, 300, QtCore.Qt.KeepAspectRatio)
                self.label5.setPixmap(pix)
            else:
                try:
                    req = requests.get('https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fy.gtimg.cn%2Fmusic%2Fphoto_new%2FT001R300x300M000002ztBMe06cOx0.jpg%3Fmax_age%3D2592000&refer=http%3A%2F%2Fy.gtimg.cn&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1625464213&t=a30c07bda8c2ab7d8001a59353e936e0')

                    checkfile  = open('ls2.png','w+b')
                    for i in req.iter_content(100000):
                        checkfile.write(i)

                    checkfile.close()
                    lsfile = './ls2.png'
                    safile = './2.png'
                    draw(lsfile,safile)
                except:
                    print ('download error')
                    pix_img = QtGui.QPixmap('./2.png')
                    pix = pix_img.scaled(300, 300, QtCore.Qt.KeepAspectRatio)
                    self.label5.setPixmap(pix)
                    pass
                pass


    def bofang(self, num):
        try:
            global pause
            self.photo(num)
            self.console_button_3.setIcon(qtawesome.icon('fa.pause', color='#F76677', font=18))
            pause = False
            # QMessageBox.information(self, "ListWidget", "你选择了: "+item.text())# 显示出消息提示框
            fill = SongPath[num]
            print(fill)
            try:
                pygame.mixer.stop()
            except:
                pass
            pygame.mixer.init()
            try:
                self.Timer = QTimer()
                self.Timer.start(500)
            except:
                pass
            pygame.mixer.music.load(SongPath[num])  # 载入音乐
            pygame.mixer.music.play()  # 播放音乐


        except:
            time.sleep(0.1)
            print ('system error')
            self.next()
            pass

    def playmode(self):
        global play
        try:
            if play == 'shun':
                play = 'shui'
                print('随机播放')
                self.label2.setText("当前为随机播放")
                try:
                    self.console_button_6.setIcon(qtawesome.icon('fa.random', color='#3FC89C', font=18))
                    print('done')
                except:
                    print('none')
                    pass

                # self.left_shui.setText('切换为单曲循环')
            elif play == 'shui':
                play = 'always'
                print('单曲循环')
                self.label2.setText("当前为单曲循环")
                try:
                    self.console_button_6.setIcon(qtawesome.icon('fa.retweet', color='#3FC89C', font=18))
                    print('done')
                except:
                    print('none')


                # self.left_shui.setText('切换为顺序播放')
            elif play == 'always':
                play = 'shun'
                print('顺序播放')
                self.label2.setText("当前为顺序播放")
                try:
                    self.console_button_6.setIcon(qtawesome.icon('fa.align-center', color='#3FC89C', font=18))
                    print('done')
                except:
                    print('none')

                # self.left_shui.setText('切换为随机播放')
        except:
            print('error')
            pass

    def action(self):
        a = 1
        global num
        while a < 2:
            # print ('checking')
            try:
                time.sleep(1)
                if not pygame.mixer.music.get_busy() and pause == False:
                    if play == 'shun':
                        print('shuning')
                        self.next()
                    elif play == 'shui':
                        print('shuiing')
                        self.shui()
                    elif play == 'always':
                        print('alwaysing')
                        self.always()

            except:
                print('no')
                pass
        else:
            pygame.mixer.music.stop()

    def nextion(self):

            try:
                    if play == 'shun':
                        print('shuning')
                        self.next()
                    elif play == 'shui':
                        print('shuiing')
                        self.shui()
                    elif play == 'always':
                        print('alwaysing')
                        self.next()

            except:
                print('no')
                pass
    def add(self):
        try:

            global SongPath
            global num
            global filew
            global asas
            num = 0
            fileN = QtWidgets.QFileDialog.getExistingDirectory(None, "选取文件夹", "")
            self.listwidget.clear()
            filew = fileN + '/'
            asas = filew
            l1 = [name for name in os.listdir(fileN) if name.endswith('.mp3')]
            l2 = [name for name in os.listdir(fileN) if name.endswith('.flac')]
            l3 = [name for name in os.listdir(fileN) if name.endswith('wma')]
            SongName = l1 + l2 + l3
            SongPath = [filew + i for i in SongName]
            print(SongPath)
            # self.Timer.timeout.connect(self.timercontorl)#时间函数,与下面的进度条和时间显示有关
            # self.label = os.path.splitext(SongName[num])#分割文件名和扩展名
            # self.label.setText(wenjianming)#设置标签的文本为音乐的名字
            print(SongPath[num])
            r = 0
            for i in SongName:
                # self.listwidget.addItem(i)#将文件名添加到listWidget

                self.listwidget.addItem(i)
                self.listwidget.item(r).setForeground(QtCore.Qt.white)
                r = r + 1
            # self.next(self)
        except:
            filew = asas

    def start(self):
        try:
            global SongPath
            global num
            global filew
            global asas
            if not os.path.exists("2.png"):
                try:
                    req = requests.get('https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fy.gtimg.cn%2Fmusic%2Fphoto_new%2FT001R300x300M000002ztBMe06cOx0.jpg%3Fmax_age%3D2592000&refer=http%3A%2F%2Fy.gtimg.cn&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1625464213&t=a30c07bda8c2ab7d8001a59353e936e0')

                    checkfile  = open('ls2.png','w+b')
                    for i in req.iter_content(100000):
                        checkfile.write(i)

                    checkfile.close()
                    lsfile = './ls2.png'
                    safile = './2.png'
                    draw(lsfile,safile)
                except:
                    print ('download error')
                    pass
            fileN = QtWidgets.QFileDialog.getExistingDirectory(None, "选取文件夹", "")

            filew = fileN + '/'
            asas = filew
            l1 = [name for name in os.listdir(fileN) if name.endswith('.mp3')]
            l2 = [name for name in os.listdir(fileN) if name.endswith('.flac')]
            l3 = [name for name in os.listdir(fileN) if name.endswith('wma')]
            SongName = l1 + l2 + l3
            SongPath = [filew + i for i in SongName]
            print(SongPath)
            pygame.mixer.init()
            self.Timer = QTimer()
            self.Timer.start(500)
            # self.Timer.timeout.connect(self.timercontorl)#时间函数,与下面的进度条和时间显示有关
            # self.label = os.path.splitext(SongName[num])#分割文件名和扩展名
            # self.label.setText(wenjianming)#设置标签的文本为音乐的名字
            print(SongPath[num])
            self.photo(num)
            a, f = os.path.split(SongPath[num])  # 分割文件名
            f, ex = os.path.splitext(f)
            # self.label.setText(wenjianming)#设置标签的文本为音乐的名字
            self.label.setText(f)
            pygame.mixer.music.load(SongPath[num])  # 载入音乐
            pygame.mixer.music.play()  # 播放音乐2
            self.label3.setText(str(pygame.mixer.music.get_volume()))
            r = 0
            for i in SongName:
                # self.listwidget.addItem(i)#将文件名添加到listWidget

                self.listwidget.addItem(i)
                self.listwidget.item(r).setForeground(QtCore.Qt.white)
                r = r + 1
            # self.next(self)
        except:
            return

    def change_func(self, listwidget):
        global num
        item = QListWidgetItem(self.listwidget.currentItem())
        print(item.text())
        # print (item.flags())
        num = int(listwidget.currentRow())
        a, f = os.path.split(SongPath[num])  # 分割文件名
        f, ex = os.path.splitext(f)
        # self.label.setText(wenjianming)#设置标签的文本为音乐的名字
        self.label.setText(f)
        print(listwidget.currentRow())
        self.bofang(num)

    def pause(self):
        global pause
        if pause:
            try:
                pygame.mixer.music.unpause()
            except:
                pass
            self.console_button_3.setIcon(qtawesome.icon('fa.pause', color='#3FC89C', font=18))
            pause = False
        else:
            try:
                pygame.mixer.music.pause()
            except:
                pass
            self.console_button_3.setIcon(qtawesome.icon('fa.play', color='#F76677', font=18))
            pause = True




    def voiceup(self):
        print('up')
        global voice
        voice += 0.1
        if voice > 1:
            voice = 1
        pygame.mixer.music.set_volume(voice)
        self.label3.setText(str(pygame.mixer.music.get_volume()))

    def voicedown(self):
        print('down')
        global voice
        voice -= 0.1
        if voice < 0:
            voice = 0
        pygame.mixer.music.set_volume(voice)
        self.label3.setText(str(pygame.mixer.music.get_volume()))

    def shui(self):
        global num
        global SongPath
        q = int(len(SongPath) - 1)
        num = int(random.randint(1, q))
        try:
            print('shui')
            pygame.mixer.init()
            self.Timer = QTimer()
            self.Timer.start(500)
            # self.Timer.timeout.connect(self.timercontorl)#时间函数,与下面的进度条和时间显示有关
            a, f = os.path.split(SongPath[num])  # 分割文件名
            f, ex = os.path.splitext(f)
            # self.label.setText(wenjianming)#设置标签的文本为音乐的名字
            self.label.setText(f)
            pygame.mixer.music.load(SongPath[num])  # 载入音乐
            pygame.mixer.music.play()  # 播放音乐

        except:
            pass

    def next(self):
        global num
        global SongPath
        if num == len(SongPath) - 1:
            print('冇')
            num = 0
        else:
            num = num + 1
        try:
            self.photo(num)
            print('next')
            pygame.mixer.init()
            self.Timer = QTimer()
            self.Timer.start(500)
            # self.Timer.timeout.connect(self.timercontorl)#时间函数,与下面的进度条和时间显示有关
            a, f = os.path.split(SongPath[num])  # 分割文件名
            f, ex = os.path.splitext(f)
            # self.label.setText(wenjianming)#设置标签的文本为音乐的名字
            self.label.setText(f)
            pygame.mixer.music.load(SongPath[num])  # 载入音乐
            pygame.mixer.music.play()  # 播放音乐

        except:
            pass

    def always(self):
        try:
            self.photo(num)
            print('always')
            pygame.mixer.init()
            self.Timer = QTimer()
            self.Timer.start(500)
            # self.Timer.timeout.connect(self.timercontorl)#时间函数,与下面的进度条和时间显示有关
            a, f = os.path.split(SongPath[num])  # 分割文件名
            f, ex = os.path.splitext(f)
            # self.label.setText(wenjianming)#设置标签的文本为音乐的名字
            self.label.setText(f)
            pygame.mixer.music.load(SongPath[num])  # 载入音乐
            pygame.mixer.music.play()  # 播放音乐

        except:
            pass

    def last(self):
        global num
        global SongPath
        if num == 0:
            print('冇')
            num = len(SongPath) - 1
        else:
            num = num - 1
        try:
            self.photo(num)
            pygame.mixer.init()
            self.Timer = QTimer()
            self.Timer.start(500)
            a, f = os.path.split(SongPath[num])  # 分割文件名
            f, ex = os.path.splitext(f)
            # self.label.setText(wenjianming)#设置标签的文本为音乐的名字
            self.label.setText(f)
            pygame.mixer.music.load(SongPath[num])  # 载入音乐
            pygame.mixer.music.play()  # 播放音乐
        except:
            pass

    def keyPressEvent(self, QKeyEvent):
        if QKeyEvent.modifiers() == Qt.ControlModifier and QKeyEvent.key() == Qt.Key_A:  # 键盘某个键被按下时调用
            print('surpise')

def crop_max_square(pil_img):
    return crop_center(pil_img, min(pil_img.size), min(pil_img.size))


def crop_center(pil_img, crop_width, crop_height):
    img_width, img_height = pil_img.size
    return pil_img.crop(((img_width - crop_width) // 2,
                         (img_height - crop_height) // 2,
                         (img_width + crop_width) // 2,
                         (img_height + crop_height) // 2))

def mask_circle_transparent(pil_img, blur_radius, offset=0):
    offset = blur_radius * 2 + offset
    mask = Image.new("L", pil_img.size, 0)
    draw = ImageDraw.Draw(mask)
    draw.ellipse((offset, offset, pil_img.size[0] - offset, pil_img.size[1] - offset), fill=255)
    mask = mask.filter(ImageFilter.GaussianBlur(blur_radius))

    result = pil_img.copy()
    result.putalpha(mask)
    return result

def draw(lsfile,safile):
    markImg = Image.open(lsfile)
    thumb_width = 600

    im_square = crop_max_square(markImg).resize((thumb_width, thumb_width), Image.LANCZOS)
    im_thumb = mask_circle_transparent(im_square, 0)
    im_thumb.save(safile)
    os.remove(lsfile)

def main():
    app = QtWidgets.QApplication(sys.argv)
    gui = MainUi()
    gui.show()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

#啦啦啦啦啦啦啦啦啦,今天2021/6/1,儿童节快乐鸭[]~( ̄▽ ̄)~*

接下来还会出网络版本,敬请期待
先透露一点源码吧

import requests
import re
from bs4 import BeautifulSoup

headers = {
    'Host': 'music.163.com',
    'Referer': 'http://music.163.com/',

    'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36'
}

url = 'http://music.163.com/discover/toplist'
r = requests.session()
r = BeautifulSoup(r.get(url, headers=headers).content,features="lxml")
result = r.find('ul', {'class': 'f-hide'}).find_all('a')
# print(reslut)

music = []  # 用于接受返回值
musicpath = []
for mu in result:
    # print('{}:{}'.format(music.text,music['href']))
    c = '{}:{}'.format(mu.text, mu['href'])
    k,p = c.split('=')
    #a = filter(str.isdigit,  p)
    b = ("https://music.163.com/song/media/outer/url?id=" + str(p) + ".mp3")
    music.append(c)
    musicpath.append(b)
print(music)
music[1]
from pprint import pprint  # 格式化输出
print(musicpath)
num = 1
print (musicpath[num])
url = 'https://music.163.com/song/media/outer/url?id=1835009703.mp3'
data = requests.get(str(url)).content
with open('1.mp3','wb')as f:
    f.write(data)
  • 7
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
要使用Python编写QQ音乐播放器,你需要掌握以下几个步骤: 1. 安装必要的库:你需要安装PyQt5和Requests库。PyQt5是Python的GUI框架,Requests库用于从QQ音乐API获取音乐歌曲和封面图片。 2. 获取QQ音乐歌曲信息:从QQ音乐API获取音乐歌曲信息,包括歌曲名、歌手、专辑、歌曲链接和封面图片等。 3. 创建播放器界面:使用PyQt5创建音乐播放器的界面,包括播放、暂停、上一首、下一首和音量控制等按钮。 4. 播放音乐:使用Python的PyGame库播放音乐,将获取到的音乐链接传递给PyGame库进行播放。 下面是一个简单的示例代码: ```python import sys import requests import pygame from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QHBoxLayout, QLabel, QPushButton, QSlider from PyQt5.QtGui import QPixmap from PyQt5.QtCore import Qt, QSize class QQMusicPlayer(QWidget): def __init__(self): super().__init__() self.init_ui() self.music_list = [] self.current_music_index = 0 self.playing = False self.volume = 50 pygame.init() def init_ui(self): self.resize(400, 300) self.setWindowTitle('QQ Music Player') self.setWindowFlags(Qt.WindowCloseButtonHint) self.title_label = QLabel('QQ Music Player') self.title_label.setAlignment(Qt.AlignCenter) self.album_cover_label = QLabel(self) self.album_cover_label.setFixedSize(200, 200) self.album_cover_label.setPixmap(QPixmap('cover.jpg').scaled(QSize(200, 200), Qt.KeepAspectRatio)) self.song_name_label = QLabel('No song') self.song_name_label.setAlignment(Qt.AlignCenter) self.singer_label = QLabel('No singer') self.singer_label.setAlignment(Qt.AlignCenter) self.play_button = QPushButton('Play') self.play_button.clicked.connect(self.play_pause_music) self.prev_button = QPushButton('Prev') self.prev_button.clicked.connect(self.play_prev_music) self.next_button = QPushButton('Next') self.next_button.clicked.connect(self.play_next_music) self.volume_slider = QSlider(Qt.Horizontal) self.volume_slider.setMinimum(0) self.volume_slider.setMaximum(100) self.volume_slider.setValue(50) self.volume_slider.valueChanged.connect(self.change_volume) vbox_layout = QVBoxLayout() vbox_layout.addWidget(self.title_label) vbox_layout.addWidget(self.album_cover_label) vbox_layout.addWidget(self.song_name_label) vbox_layout.addWidget(self.singer_label) hbox_layout = QHBoxLayout() hbox_layout.addWidget(self.prev_button) hbox_layout.addWidget(self.play_button) hbox_layout.addWidget(self.next_button) vbox_layout.addLayout(hbox_layout) vbox_layout.addWidget(self.volume_slider) self.setLayout(vbox_layout) def get_music_list(self, keyword): url = 'https://c.y.qq.com/soso/fcgi-bin/client_search_cp?new_json=1&remoteplace=txt.yqq.song&searchid=70837171441911197&t=0&aggr=1&cr=1&catZhida=1&lossless=0&flag_qc=0&p=1&n=20&w=' + keyword headers = { 'referer': 'https://y.qq.com/portal/search.html' } response = requests.get(url, headers=headers) json_data = response.json() music_list = [] for item in json_data['data']['song']['list']: music = { 'name': item['name'], 'singer': item['singer'][0]['name'], 'album': item['album']['name'], 'cover': item['album']['mid'], 'url': self.get_music_url(item['mid']) } music_list.append(music) self.music_list = music_list self.current_music_index = 0 self.update_ui() def get_music_url(self, mid): url = 'https://u.y.qq.com/cgi-bin/musicu.fcg?callback=getplaysongvkey5340713917016285&g_tk=5381&jsonpCallback=getplaysongvkey5340713917016285&loginUin=0&hostUin=0&format=jsonp&inCharset=utf8&outCharset=utf-8&notice=0&platform=yqq.json&needNewCode=0&data=%7B%22req_0%22%3A%7B%22module%22%3A%22vkey.GetVkeyServer%22%2C%22method%22%3A%22CgiGetVkey%22%2C%22param%22%3A%7B%22guid%22%3A%227320798373%22%2C%22songmid%22%3A%5B%22' + mid + '%22%5D%2C%22songtype%22%3A%5B0%5D%2C%22uin%22%3A%220%22%2C%22loginflag%22%3A1%2C%22platform%22%3A%2220%22%7D%7D%2C%22comm%22%3A%7B%22uin%22%3A0%2C%22format%22%3A%22json%22%2C%22ct%22%3A20%2C%22cv%22%3A0%7D%7D' headers = { 'referer': 'https://y.qq.com/' } response = requests.get(url, headers=headers) json_data = response.json() return 'http://isure.stream.qqmusic.qq.com/' + json_data['req_0']['data']['midurlinfo'][0]['purl'] def update_ui(self): if len(self.music_list) == 0: self.song_name_label.setText('No song') self.singer_label.setText('No singer') self.album_cover_label.setPixmap(QPixmap('cover.jpg').scaled(QSize(200, 200), Qt.KeepAspectRatio)) else: music = self.music_list[self.current_music_index] self.song_name_label.setText(music['name']) self.singer_label.setText(music['singer']) url = 'https://y.gtimg.cn/music/photo_new/T002R300x300M000' + music['cover'] + '.jpg' response = requests.get(url) image_data = response.content pixmap = QPixmap() pixmap.loadFromData(image_data) self.album_cover_label.setPixmap(pixmap.scaled(QSize(200, 200), Qt.KeepAspectRatio)) def play_pause_music(self): if len(self.music_list) == 0: return if self.playing: pygame.mixer.music.pause() self.play_button.setText('Play') self.playing = False else: pygame.mixer.music.unpause() self.play_button.setText('Pause') self.playing = True def play_prev_music(self): if len(self.music_list) == 0: return self.current_music_index = (self.current_music_index - 1) % len(self.music_list) self.play_music() def play_next_music(self): if len(self.music_list) == 0: return self.current_music_index = (self.current_music_index + 1) % len(self.music_list) self.play_music() def play_music(self): music = self.music_list[self.current_music_index] pygame.mixer.music.load(music['url']) pygame.mixer.music.set_volume(self.volume / 100) pygame.mixer.music.play() self.play_button.setText('Pause') self.playing = True self.update_ui() def change_volume(self, value): self.volume = value pygame.mixer.music.set_volume(self.volume / 100) if __name__ == '__main__': app = QApplication(sys.argv) player = QQMusicPlayer() player.show() sys.exit(app.exec_()) ``` 这是一个初级版本的QQ音乐播放器,它可以通过关键字搜索QQ音乐中的歌曲,并播放它们。你可以根据自己的需要对代码进行修改和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值