Python GUI编程:音乐播放器(多线程爬虫进度条文件)

Posted il_持之以恒_li

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python GUI编程:音乐播放器(多线程爬虫进度条文件)相关的知识,希望对你有一定的参考价值。

文章目录

1. 程序运行结果

Python实现音乐播放器(爬虫、多线程、进度条、文件)

2.程序实现原理

本音乐播放器GUI方面运用Python的tkinter实现,播放的音乐来自网络爬虫和本电脑已经有的。为了使整个程序运行起来不卡顿,运用多线程[不运用多线程会出现卡顿现象,读者可以看看小编之前的文章,里面有一篇是关于Python实现音乐播放器的,当时效果就是出现卡顿]。

3. GUI布局

说到布局,tkinter提供的有3种,小编使用的是grid布局,这种布局很容易让人理解自己做的一些控件、标签等在整个窗口的位置。

布局说明
pack()按照控件的添加顺序其进行排列,遗憾的是此方法灵活性较差
grid()以行和列(网格)形式对控件进行排列,此种方法使用起来较为灵活
place()可以指定组件大小以及摆放位置,三个方法中最为灵活的布局方法

4. 功能介绍


整个音乐播放器的效果就是上述那样。

  1. 如果要搜索线上音乐,直接在搜索框里输入歌名,然后按电脑键盘的Enter,然后搜索框下面的列表框里就会给出搜索的结果,如果想听其中的一首,鼠标点击到那一首歌曲那然后双击鼠标左键,即可播放音乐。如果我们想把播放的音乐收藏,直接点击鼠标右键即可;
  2. 如果我们想听我的收藏里的歌曲,直接点击我的收藏,然后列表框里的内容就会变成已经收藏的音乐,此时不是双击鼠标左键进行播放,而是选中其中一首,然后点击下面的播放按钮进行播放,如果我们想要歌曲循环播放,点击下面的循环播放即可(注:循环播放只支持收藏的音乐);
  3. 调节音量的大小,使用Scale控件(循环播放前面那个玩意);
  4. 设置按钮可以用来设置歌词的字体颜色、字体大小、字体格式和背景颜色,用的是下拉框,设置之后,保存即可。

5. 代码实现

代码有点多,且涉及到文件读写,就不不把代码一一粘贴出来了,想要的读者直接去资源下载即可。
这是其中一部分。

import tkinter as tk
import tkinter.ttk as ttk
from Crawl2.music_player.MusicCrawl import MusicCrawl
import threading
import time
from pydub import Audiosegment as pd
from pygame import mixer
import json

class MusicTk:

    def __init__(self):
        self.__top = tk.Tk()
        self.__size = [1150,700]
        # 窗口大小 宽 高
        self.__search2 = None
        self.__listbox = None
        self.__listMusic = None
        self.__mixer = None
        self.__canvas = None
        # 画布
        self.__progressBar = None
        # 进度条
        self.__time1 = None
        self.__time2 = None
        self.__scale = None
        self.__temp = None
        self.__listInfo = None
        self.__myCollections = None

        self.__data = ['微软雅黑',12,'white','black']

        self.__cbox = None
        self.__cbox2 = None
        self.__cbox3 = None
        self.__cbox4 = None
        self.__radioBtn = None
        self.__radioBtnV = None
        self.__num1 = 0
        self.__state = 0
        self.__keyword = ''
        self.win2 = None

    # 布局
    def sectionOne(self):
        win = self.__top
        win.geometry(f'self.__size[0]xself.__size[1]')
        win.resizable(height=0,width=0)

        v = tk.StringVar(value="搜索音乐")
        label_1 = tk.Entry(win,textvariable=v, font=('微软雅黑', 12),width=24)
        label_1.grid(row=0, column=0,ipady=2,ipadx=2,padx=20,sticky=tk.W)
        # 搜索框
        label_1.bind('<ButtonPress-1>',self.fun1)

        label_1.bind('<Return>',self.fun2)

        self.__search2 = label_1

        frame = tk.Frame(win)
        frame.grid(row=0, column=1, sticky=tk.W)

        tk.Button(frame, text='我的收藏',font=('', 12),command=self.__myCollection).grid(row=0, column=0, ipadx=1, ipady=1, sticky=tk.W)
        # 我的收藏 按钮

        tk.Button(frame,text='设置',font=('', 12),command=self.__setButton).grid(row=0,column=1,ipadx=1,ipady=1,padx=2,sticky=tk.W)
        # 设置按钮

        frameMiddle = tk.Frame(win)
        frameMiddle.grid(row=1,column=0,columnspan=2)

        list_box = tk.Listbox(frameMiddle, font=('', 12,'bold'), width=30,height=35,selectmode="single",selectbackground='red')
        list_box.grid(row=0, column=0)
        self.__listbox = list_box

        self.__listbox.bind('<Double-Button-1>',func=self.__fun4)
        # 双击鼠标左键播放音乐
        self.__listbox.bind('<ButtonPress-3>',func=self.__restore)
        # 单击鼠标右键收藏音乐

        canvas = tk.Canvas(frameMiddle,bg=self.__data[3],width=900,height=600,confine=True,relief='groove')
        canvas.grid(row=0,column=1)
        # 画布
        self.__canvas = canvas

        sv = tk.Scrollbar(frameMiddle)
        sv.grid(row=0, column=2)
        canvas.config(yscrollcommand=sv.set)
        canvas.config(scrollregion=(0, 0, 900, 3000))
        sv.config(command=canvas.yview)
        canvas.config(yscrollincrement=1)
        canvas.bind("<MouseWheel>", self.event1)

        progressBar = ttk.Progressbar(win)
        # 进度条
        progressBar.grid(row=2,column=0,columnspan=2)
        progressBar['length'] = self.__size[0]-400
        progressBar['value'] = 0
        # 进度条赋初值为0
        self.__progressBar = progressBar

        frame2 = tk.Frame(win)
        frame2.grid(row=3,column=0,columnspan=2)

        label_2 = tk.Label(frame2,text='00:00',font=('',12))
        label_2.grid(row=0,column=0,sticky=tk.W)
        self.__time1 = label_2

        tk.Button(frame2,text='上一首',font=('',12)).grid(row=0,column=1)
        tk.Button(frame2, text='播放',font=('',12),command=self.__play).grid(row=0, column=2)
        tk.Button(frame2, text='暂停',font=('',12),command=self.__stop).grid(row=0, column=3)
        tk.Button(frame2, text='下一首', font=('', 12)).grid(row=0, column=4)

        label_3 = tk.Label(frame2, text='00:00', font=('', 12))
        label_3.grid(row=0, column=5, sticky=tk.E)
        self.__time2 = label_3

        self.__scale = tk.Scale(frame2,from_=0,to=100,resolution=2,length=150,orient=tk.HORIZONTAL,font=('',12),command=self.fun6)
        self.__scale.grid(row=0,column=6,sticky=tk.E,padx=10)
        self.__scale.set(100)

        self.__radioBtnV = tk.IntVar()
        self.__radioBtn = tk.Checkbutton(frame2,variable=self.__radioBtnV,text='循环播放',onvalue=1,command=self.__getRadioBtn)
        self.__radioBtn.grid(row=0,column=7,sticky=tk.E,padx=10)
        # 复选框

        tk.mainloop()


    def __getRadioBtn(self):
        self.__num1 = self.__radioBtnV.get()

    # 设置按钮
    def __setButton(self):


        win2 = tk.Tk()

        self.win2 = win2

        tk.Label(win2,text='播放字体',font=('微软雅黑',10)).grid(row=0,column=0)
        # 下拉框
        cbox = ttk.Combobox(win2)
        cbox.grid(row=0,column=1)
        cbox['value'] = ('微软雅黑','华文宋体','华文宋体')
        cbox.current(0)

        tk.Label(win2,text='字体大小',font=('微软雅黑',10)).grid(row=1,column=0)

        cbox2 = ttk.Combobox(win2)
        cbox2.grid(row=1, column=1)
        cbox2['value'] = tuple([str(i) for i in range(12,19)])
        cbox2.current(0)

        tk.Label(win2, text='字体颜色', font=('微软雅黑', 10)).grid(row=2, column=0)
        cbox3 = ttk.Combobox(win2)
        cbox3.grid(row=2, column=1)
        cbox3['value'] = ('white','red','black')
        cbox3.current(0)

        tk.Label(win2, text='背景颜色', font=('微软雅黑', 10)).grid(row=3, column=0)
        cbox4 = ttk.Combobox(win2)
        cbox4.grid(row=3, column=1)
        cbox4['value'] = ('black','white')
        cbox4.current(0)

        self.__cbox = cbox
        self.__cbox2 = cbox2
        self.__cbox3 = cbox3
        self.__cbox4 = cbox4


        saveBtn = tk.Button(win2,text='保存',font=('微软雅黑',10),command=self.__reset)
        saveBtn.grid(row=4,column=0,columnspan=2)

        win2.mainloop()

    def __reset(self):
        font = self.__cbox.get()
        size = self.__cbox2.get()
        fontColor = self.__cbox3.get()
        bgColor = self.__cbox4.get()

        self.__data = [font,size,fontColor,bgColor]

        dict2 = dict()
        dict2['font'] = font
        dict2['size'] = size
        dict2['fontColor'] = fontColor
        dict2['bgColor'] = bgColor
        str2 = json.dumps(dict2)

        with open(file='data.json',mode='w',encoding='utf-8') as f:
            f.write(str2)

        self.win2.destroy()

    # 我的收藏按钮
    def __myCollection(self):
        with open(file='Collection.json',mode='r',encoding='utf-8') as f:
            str_1 = f.read()

        dict1 = json.loads(str_1)

        self.__myCollections = dict1

        self.__listbox.delete(0, tk.END)
        # 清空列表框里的内容
        for key in dict1:
            self.__listbox.insert(tk.END, f'key')

        self.__state = 1


    def __restore(self,event):
        with open(file='Collection.json',mode='r',encoding='utf-8') as f:
            str1 = f.read()
        if str1 != '':
            dict1 = json.loads(str1)
        else:
            dict1 = 
        listBox = self.__listbox
        v = listBox.get(listBox.curselection())
        if v not in dict1:
            dict1[v] = [self.__listInfo[1],self.__listInfo[2],self.__listInfo[3]]

        str1 = json.dumps(dict1)
        with open(file='Collection.json',mode='w',encoding='utf-8') as f:
            f.write(str1)


    def fun6(self,value):
        if self.__mixer is not None:
            mixer = self.__mixer
            mixer.music.set_volume(int(value)/100)


    def event1(self,event):
        number = int(-event.delta / 60)
        self.__canvas.yview_scroll(number, 'units')

    def __play(self):
        # if self.__mixer is not None:
        #     self.__mixer.music.unpause()
        #     self.__temp = None
        listBox = self.__listbox
        v = listBox.get(listBox.curselection())

        dict1 = self.__myCollections
        list1 = dict1[v]
        self.__keyword = v


        musicPlayThread = threading.Thread(target=self.threadFun1, args=([True,0,0,list1[2]],))
        lyricsThread = threading.Thread(target=self.threadFun2, args=(list1[0],))
        progressThread = threading.Thread(target=self.threadFun3, args=(list1[1],))
        timeThread = threading.Thread(target=self.threadFun4, args=(list1[1],))

        musicPlayThread.start()
        lyricsThread.start()
        progressThread.start()
        timeThread.start()


    def __stop(self):
        if self.__mixer is not None:
            # self.__mixer.music.stop()
            self.__mixer.music.pause()

            self运用Java制作音乐播放器(多线程爬虫文件进度条)

Python爬虫编程思想(143):项目实战:多线程和多进程爬虫

Python爬虫编程思想(143):项目实战:多线程和多进程爬虫

使用 Python 的音乐播放器 GUI

通过网络图片小爬虫对比Python中单线程与多线(进)程的效率

Python挑翻音乐网,GUI实现音乐播放器,无敌Pythoner炼成记!