【发布时间】:2020-07-27 00:37:29
【问题描述】:
我的自制音乐播放器已启动并正在运行。现在是时候添加一些从当前播放的带有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:我看过这个问答:How to update the image of a Tkinter Label widget?,它使用:
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()
【问题讨论】:
标签: python image tkinter python-imaging-library