Python tkinter如何定义图像变量



我已经启动并运行了自制的音乐播放器。现在是时候添加一些从当前使用ffmpeg播放的歌曲中提取的专辑艺术作品了。我已经做了很多搜索,但不确定在tkinter中设置这个的最有效方法。粗糙的窗户模型:

+================+
|                |   Current Artist: Best Band Ever
|  (No Artwork)  |   Current Album:  Greatest Album Ever
|                |   Current Song:   Irresistible Tune
|                |   Play Progress:  99.9 seconds of: 999
+================+

窗口底部有按钮;关闭、暂停、上一个、下一个。

当抓取窗口边框进行放大时,我希望图片的大小最大,因为初始大小是200x200,这很难看到。

我的问题是:如何定义TK标签字段中的图像变量

暂时我已经将图像设置为TK字符串var:

''' Artwork image spanning 4 rows '''
self.current_song_artwork = tk.StringVar()
tk.Label(master2, text="(No Artwork)", font=(None, MON_FONTSIZE)) 
.grid(row=0, rowspan=4, column=0, sticky=tk.W)

注1:我看过这个问答;A: 如何更新Tkinter标签小部件的图像?使用:

img2 = ImageTk.PhotoImage(Image.open(path2))
panel.configure(image=img2)
panel.image = img2

这似乎是唯一的选择?

注2:首次打开顶层窗口时,不会播放歌曲,也不会显示艺术品的图像。是否需要某种占位符?

注意3:接下来,我想用音乐可视化工具(按比例缩小(、滚动歌词或滚动维基百科上的传记来替换艺术品。因此,用稳健的设计进行未来验证在今天是有意义的。

注意4:这只是我的第二个Python/Tkinter程序,下面的大部分代码都是从第一个程序复制粘贴的。第一个主要是从Stack Overflow复制和粘贴代码。任何关于减少代码行或提高效率的提示都将不胜感激!


TL;DR

完整的(不是很令人兴奋的代码(是:

def play_items(self):
''' Play 1 or more songs in listbox.selection()
"Close", "Next", "Prev" and "Pause" buttons

Selection may be artist, album or random songs. Get item tag:
Auto-starts playing first song with:
ffplay -nodisp -autoexit "/path/to/song.ext"
If Pause button pressed change text to "Play" and issue:
PID with pgrep ffplay then use kill -s STOP <PID> to suspend
If Play button pressed change text to "Pause" and issue:
PID with pgrep ffplay then use kill -s CONT <PID> to resume
'''
if len(self.listbox.selection()) == 0 :
# TODO: Dialog "Select one or more songs to play."
return
''' Make parent buttons invisible so user doesn't try to click '''
self.clear_buttons()
self.top2 = tk.Toplevel()
self.top2_is_active = True
''' Place Window top-left of parent window with PANEL_HGT padding '''
xy = (self.toplevel.winfo_x() + PANEL_HGT, 
self.toplevel.winfo_y() + PANEL_HGT)
self.top2.minsize(width=BTN_WID * 10, height=PANEL_HGT * 4)
self.top2.geometry('+%d+%d'%(xy[0], xy[1]))
self.top2.title("Playing Selected Songs")
self.top2.configure(background="Gray")
self.top2.columnconfigure(0, weight=1)
self.top2.rowconfigure(0, weight=1)
''' Create master frame '''
master2 = tk.Frame(self.top2, borderwidth=BTN_BRD_WID, relief=tk.RIDGE)
master2.grid(sticky=tk.NSEW)
''' Artwork image spanning 4 rows '''
self.current_song_artwork = tk.StringVar()
tk.Label(master2, text="(No Artwork)", font=(None, MON_FONTSIZE)) 
.grid(row=0, rowspan=4, column=0, sticky=tk.W)
''' Current artist '''
self.current_song_artist = tk.StringVar()
tk.Label(master2, text="Current Artist:", font=(None, MON_FONTSIZE)) 
.grid(row=0, column=1, sticky=tk.W)
tk.Label(master2, text="", textvariable=self.current_song_artist, 
font=(None, MON_FONTSIZE)).grid(row=0, column=2, 
sticky=tk.W)
''' Current album '''
self.current_song_album = tk.StringVar()
tk.Label(master2, text="Current Album:", font=(None, MON_FONTSIZE)) 
.grid(row=1, column=1, sticky=tk.W)
tk.Label(master2, text="", textvariable=self.current_song_album, 
font=(None, MON_FONTSIZE)).grid(row=1, column=2, 
sticky=tk.W)
''' Current song '''
self.current_song_path = ""
self.current_song_name = tk.StringVar()
tk.Label(master2, text="Current Song:", font=(None, MON_FONTSIZE)) 
.grid(row=2, column=1, sticky=tk.W)
tk.Label(master2, text="", textvariable=self.current_song_name, 
font=(None, MON_FONTSIZE)).grid(row=2, column=2, 
sticky=tk.W)
''' Progress of play '''
self.current_progress = tk.StringVar()
tk.Label(master2, text="Play Progress:", font=(None, MON_FONTSIZE)) 
.grid(row=3, column=1, sticky=tk.W)
tk.Label(master2, text="", textvariable=self.current_progress, 
font=(None, MON_FONTSIZE)).grid(row=3, column=2, 
sticky=tk.W)
''' Frame for Buttons '''
frame3 = tk.Frame(self.top2, bg="Blue", borderwidth=BTN_BRD_WID, 
relief=tk.GROOVE)
frame3.grid(row=2, column=0, sticky=tk.NSEW)
frame3.grid_rowconfigure(0, weight=1)
frame3.grid_columnconfigure(0, weight=0)
button = tk.Button(frame3, text="✘ Close", width=BTN_WID, 
command=self.play_close)
button.grid(row=0, column=0, padx=2, sticky=tk.W)
''' Close Button '''
self.top2.bind("<Escape>", self.play_close)
self.top2.protocol("WM_DELETE_WINDOW", self.play_close)
''' Pause/Play Button '''
self.pp_state = "Playing"     
self.pp_play_text = "▶  Play"
self.pp_pause_text = "❚❚ Pause"
self.pp_button_text = self.pp_pause_text
self.pp_button = tk.Button(frame3, text=self.pp_button_text, 
width=BTN_WID, command=self.pp_toggle)
self.pp_button.grid(row=0, column=1, padx=2)
''' Next/Prev Button '''
# U+1f844 🡄         U+1f846 🡆
# U_1f808 🠈         I+1f80a 🠊
prevbutton = tk.Button(frame3, text="🠈  Previous", width=BTN_WID, 
command=lambda s=self: s.get_setting('prev'))
prevbutton.grid(row=0, column=2, padx=2, sticky=tk.W)
nextbutton = tk.Button(frame3, text="Next 🠊 ", width=BTN_WID, 
command=lambda s=self: s.get_setting('next'))
nextbutton.grid(row=0, column=3, padx=2, sticky=tk.W)
''' Start at first listbox entry seleected '''
self.get_setting('ZERO')            # Set self.ndx to 0
self.listbox.update_idletasks()
self.play_forever()

首先,这是一个非常全面的问题。这将有助于你和未来的谷歌搜索。

这是可行的,但有几个问题需要注意,即将图像及其外部标签保存到类中。我在这里有一个简单的例子,它将运行、放置和显示标签上的图像。

import tkinter as tk
from PIL import Image,ImageTk
class Player:
def __init__(self):
self.root = tk.Tk()
self.artwork_label = tk.Label()
self.artwork_label.pack()
self.img = ImageTk.PhotoImage(Image.open(path))
self.artwork_label.configure(image=self.img)

path = ...
player = Player()

将这样的内容编辑到你的中,如果你仍然被卡住,请发表评论,我会帮你解决更多问题。

最新更新