You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python Tkinter按钮点击更换图片问题:音乐播放器播放/暂停图标切换

校内音乐库播放器开发需求

我正在使用Python开发我的第一个校内项目音乐库播放器,当前需要实现的功能为:点击显示三角形图标的“PLAY”按钮时,修改该按钮对应的图片路径或关联变量,将按钮图标切换为两条平行竖线的“PAUSE”样式。我猜测该功能需要借助.set()方法实现,但我刚接触Python仅一周,不清楚具体的实现方式。

项目完整代码

#     GUI     #
import tkinter as tk
from tkinter import *
from tkinter import filedialog


#     AUDIO   #
from pygame import mixer

#     DIRECTORY NAVIGATION   #
from os import walk

#     EXCEPTION HANDLER   #
import pygame

#     VOLUME CONTROL   #
from comtypes import CLSCTX_ALL
from pycaw.pycaw import AudioUtilities, IAudioEndpointVolume, ISimpleAudioVolume
from ctypes import cast, POINTER
# YOU MIGHT NEED TO PIP INSTALL THESE
# IF THOSE DONT WORK TRY
# py -m pip install [library]
# pip install pycaw
# pip install comtypes
# pip install psutil

from PIL import Image, ImageTk




class MP:
    
    def __init__(self, win):
        # Create Tkinter window
        win.geometry('600x300')
        win.title('Jared AIT Music Player')
        win.resizable(0, 0)
        win.iconbitmap('icon.ico')

        
        # StringVar to change button text later
        self.play_restart = tk.StringVar()
        self.pause_resume = tk.StringVar()
        self.play_restart.set('Play')
        self.pause_resume.set('Pause')

        # The buttons and their positions

        self.loadpngPATH = tk.StringVar()
        self.loadpngPATH.set('load.png')
        self.load_image = Image.open(self.loadpngPATH)

        resized = self.load_image.resize((50,50))

        self.login_btn = ImageTk.PhotoImage(resized)

        self.background_image = Image.open('background.png')
        back_res = self.background_image.resize((600,300))
        self.backphoto = ImageTk.PhotoImage(back_res)

        back_image = Label(image = self.backphoto)
        back_image.image = self.backphoto
        back_image.place(x = 300, y = 150, anchor = 'center')

        self.play_image = Image.open('play.png')
        play_res = self.play_image.resize((50,50))
        self.playphoto = ImageTk.PhotoImage(play_res)

        self.pause_image = Image.open('pause.png')
        pause_res = self.pause_image.resize((50,50))
        self.pausephoto = ImageTk.PhotoImage(pause_res)

        self.stop_image = Image.open('stop.png')
        stop_res = self.stop_image.resize((50,50))
        self.stop_photo = ImageTk.PhotoImage(stop_res)

        self.forward_image = Image.open('forward.png')
        forward_res = self.forward_image.resize((50,50))
        self.forward_photo = ImageTk.PhotoImage(forward_res)

        self.back_image = Image.open('back.png')
        back_res = self.back_image.resize((50,50))
        self.back_photo = ImageTk.PhotoImage(back_res)
 


        load_button = Button(win, text='Load', width=55, height = 55, font=("Arial", 10), command=self.load, image = self.login_btn, bg = 'white', borderwidth = 0, highlightthickness=0)
        load_button.place(x=50,y=250, anchor='center')

        play_button = Button(win, textvariable=self.play_restart, width=55, height = 55, font=("Arial", 10), command=self.play, image = self.playphoto, borderwidth = 0, bg = 'white', highlightthickness=0)
        play_button.place(x=150,y=250, anchor='center')

        pause_button = Button(win, textvariable=self.pause_resume, width=55, height=55, font=("Arial", 10), command=self.pause, image = pself.ausephoto, bg = 'white', borderwidth = 0, highlightthickness=0)
        pause_button.place(x=250,y=250, anchor='center')

        stop_button = Button(win,width=55, height=55, font=("Arial", 10), command=self.stop, image = self.stop_photo, borderwidth = 0, highlightthickness=0, bg="white")
        stop_button.place(x=350,y=250, anchor='center')

        next_button = Button(win ,width=55, height=55, font = ('Arial', 10), command = self.next, image = self.forward_photo, borderwidth = 0, highlightthickness=0, bg="white")
        next_button.place(x=550,y=250, anchor='center')

        back_button = Button(win ,width=55, height=55, font = ('Arial', 10), command = self.back, image = self.back_photo, borderwidth = 0, highlightthickness=0, bg="white")
        back_button.place(x=450,y=250, anchor='center')


        #SLIDERS
        volume_slider = Scale(win, from_=100, to=0, orient=VERTICAL, command=self.volume, length=125)
        volume_slider.grid(row=0, column=1)



 
 

        self.music_file = False
        self.playing_state = False
        mainloop()

        
#IMAGE IMAGE IMAGE IMAGE IMAGE IMAGE IMAGE IMAGE IMAGE IMAGE IMAGE IMAGE IMAGE IMAGE IMAGE IMAGE IMAGE IMAGE



#IMAGE IMAGE IMAGE IMAGE IMAGE IMAGE IMAGE IMAGE IMAGE IMAGE IMAGE IMAGE IMAGE IMAGE IMAGE IMAGE IMAGE IMAGE


        
        
    def volume(self,volume_level):
        #       THIS INITIALISES THE VOLUME CONTROL     #
        devices = AudioUtilities.GetSpeakers()
        interface = devices.Activate(
        IAudioEndpointVolume._iid_, CLSCTX_ALL, None)
        volume = cast(interface, POINTER(IAudioEndpointVolume))

        #       THIS SETS THE VOLUME    #
        volume.SetMasterVolumeLevelScalar(int(volume_level)/100, None)

        

    def load(self):
        self.music_file = filedialog.askopenfilename(initialdir="/AIT Python 1/Assets", title="Select a song", filetypes=(("wav files", "*.wav"),("all files", "*.*"),("mp3 files", "*.mp3")))
        print("Loaded:", self.music_file)
        self.play_restart.set('Play')

    

    def play(self):
        if self.music_file:
            mixer.init()
            mixer.music.load(self.music_file)
            mixer.music.play()
            self.playing_state = False
            self.play_restart.set('Restart')
            self.pause_resume.set('Pause')


    def pause(self):
        if not self.playing_state:
            mixer.music.pause()
            self.playing_state = True
            self.pause_resume.set('Resume')

        else:
            mixer.music.unpause()
            self.playing_state = False
            self.pause_resume.set('Pause')

    def stop(self):
        mixer.music.stop()

    ########################################################################################################       
    def next(self):
        self.file_path = (self.music_file.rsplit("/",1))[0].replace("/","\\")
        if "/" in self.music_file:
            self.file_name = self.music_file.rsplit("/",1)[1]
        else:
            self.file_name = self.music_file

        self.filenames = next(walk(self.file_path), (None, None, []))[2]
        self.file_count = 0

        for i in self.filenames:
            if i == self.file_name:
                break
            self.file_count += 1

        self.next_file = self.file_count + 1
        self.directory_limit = len(self.filenames)
        if self.next_file == self.directory_limit:
            self.next_file = 0
        self.music_file = self.file_path + "/" + self.filenames[self.next_file]
        self.file_count = 0
        mixer.init()
        try:
            mixer.music.load(self.music_file)
        except pygame.error as message:
            while True:
                self.next_file += 1
                if self.next_file == self.directory_limit:
                    self.next_file = 0
                self.music_file = self.file_path + "/" + self.filenames[self.next_file]
                self.file_extension = self.music_file.rsplit(".",1)[1]
                if (".wav") or (".mp3") in self.file_extension:
                    mixer.music.load(self.music_file)
                    break
        
        mixer.music.play()



    def back(self):
        self.file_path = (self.music_file.rsplit("/",1))[0].replace("/","\\")
        if "/" in self.music_file:
            self.file_name = self.music_file.rsplit("/",1)[1]
        else:
            self.file_name = self.music_file

        self.filenames = next(walk(self.file_path), (None, None, []))[2]
        self.file_count = 0

        for i in self.filenames:
            if i == self.file_name:
                break
            self.file_count += 1

        self.back_file = self.file_count - 1
        self.directory_limit = len(self.filenames)
        if self.back_file == self.directory_limit:
            self.back_file = 0
        self.music_file = self.file_path + "/" + self.filenames[self.back_file]
        self.file_count = 0
        mixer.init()
        try:
            mixer.music.load(self.music_file)
        except pygame.error as message:
            while True:
                self.back_file += 1
                if self.back_file == self.directory_limit:
                    self.back_file = 0
                self.music_file = self.file_path + "/" + self.filenames[self.back_file]
                self.file_extension = self.music_file.rsplit(".",1)[1]
                if (".wav") or (".mp3") in self.file_extension:
                    mixer.music.load(self.music_file)
                    break
        
        mixer.music.play()


        ########################################################################################################      




root = tk.Tk()
MP(root)
root.mainloop()

图片设置相关代码片段

# The buttons and their positions


self.load_image = Image.open('load.png')
resized = self.load_image.resize((50,50))

self.login_btn = ImageTk.PhotoImage(resized)

self.background_image = Image.open('background.png')
back_res = self.background_image.resize((600,300))
self.backphoto = ImageTk.PhotoImage(back_res)

back_image = Label(image = self.backphoto)
back_image.image = self.backphoto
back_image.place(x = 300, y = 150, anchor = 'center')

self.play_image = Image.open('play.png')
play_res = self.play_image.resize((50,50))
self.playphoto = ImageTk.PhotoImage(play_res)

self.pause_image = Image.open('pause.png')
pause_res = self.pause_image.resize((50,50))
self.pausephoto = ImageTk.PhotoImage(pause_res)

self.stop_image = Image.open('stop.png')
stop_res = self.stop_image.resize((50,50))
self.stop_photo = ImageTk.PhotoImage(stop_res)

self.forward_image = Image.open('forward.png')
forward_res = self.forward_image.resize((50,50))
self.forward_photo = ImageTk.PhotoImage(forward_res)

self.back_image = Image.open('back.png')
back_res = self.back_image.resize((50,50))
self.back_photo = ImageTk.PhotoImage(back_res)




load_button = Button(win, text='Load', width=55, height = 55, font=("Arial", 10), command=self.load, image = self.login_btn, bg = 'white', borderwidth = 0, highlightthickness=0)
load_button.place(x=50,y=250, anchor='center')

play_button = Button(win, textvariable=self.play_restart, width=55, height = 55, font=("Arial", 10), command=self.play, image = self.playphoto, borderwidth = 0, bg = 'white', highlightthickness=0)
play_button.place(x=150,y=250, anchor='center')

pause_button = Button(win, textvariable=self.pause_resume, width=55, height=55, font=("Arial", 10), command=self.pause, image = self.pausephoto, bg = 'white', borderwidth = 0, highlightthickness=0)
pause_button.place(x=250,y=250, anchor='center')

stop_button = Button(win,width=55, height=55, font=("Arial", 10), command=self.stop, image = self.stop_photo, borderwidth = 0, highlightthickness=0, bg="white")
stop_button.place(x=350,y=250, anchor='center')

next_button = Button(win ,width=55, height=55, font = ('Arial', 10), command = self.next, image = self.forward_photo, borderwidth = 0, highlightthickness=0, bg="white")
next_button.place(x=550,y=250, anchor='center')

back_button = Button(win ,width=55, height=55, font = ('Arial', 10), command = self.back, image = self.back_photo, borderwidth = 0, highlightthickness=0, bg="white")
back_button.place(x=450,y=250, anchor='center')

当前GUI效果图

GUI效果图

内容的提问来源于stack exchange,提问作者Toknn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.10 22:57:02