python - 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:我看过这个问答:如何更新 Tkinter 标签小部件的图像?它使用:
img2 = ImageTk.PhotoImage(Image.open(path2))
panel.configure(image=img2)
panel.image = img2
这似乎是唯一的选择?
注 2:当顶层窗口第一次打开时,没有歌曲播放,也没有图像显示艺术作品。需要某种占位符吗?
注 3:在路上,我想用音乐可视化器(按比例缩小)、滚动歌词或滚动维基百科的传记替换艺术品。因此,具有稳健设计的面向未来的设计在今天是有意义的。
注意 4:这只是我的第二个 Python/Tkinter 程序,下面的大部分代码都是从第一个复制和粘贴的。第一个主要是从 Stack Overflow 复制和粘贴的代码。任何有关减少代码行或提高效率的提示将不胜感激!
TL;博士
完整的(不是很令人兴奋的代码)是:
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()
将类似的内容编辑到您的内容中,如果您仍然卡住,请发表评论,我会为您提供更多帮助。
推荐阅读
- angular - 如何在 Angular 5 中验证表单数组中的电子邮件或电话字段?
- jmeter - 如何从响应数据中获取 href URL 中的特定属性值
- visual-studio-2010 - 删除逗号或将逗号更改为空格 SSIS 2010
- c - 没有定义的静态函数声明
- debugging - VS Code – 通过键盘跳转到当前调试位置
- batch-file - 如何删除批处理文件中新生成的文件
- ios - CKError.Code.networkFailure 什么时候会发生?如何解决?
- c++ - 如何调用结构数组来运行?
- cryptography - 混合 Lopez Dahab 仿射坐标中的椭圆曲线点相加算法
- angular - 如何修复未定义的地图变量?