我有很多og base64图像存储在pandas dataframe df_time_text_frames
中。现在,我想制作一个简单的程序,它向我展示图像并有一个按钮NEXT或PREVIOUS来浏览图像。
我试过了:
我定义了一个函数load_next_img
,当我按下名为tk.Button
的next
时会触发该函数,然后它应该显示由全局counter
给出的帧,每当我按下这个按钮时它会递增。
尚未实现:
我会对buttom previous
有类似的功能,它会从全局变量counter
中减去1
import tkinter as tk
from PIL import ImageTk, Image
global counter
counter = 0
def load_next_img(counter):
global tk_image
image_data_base64_encoded_string = df_time_text_frames["Frame_(base_64)"][counter]
image = tk.PhotoImage(image_data_base64_encoded_string)
tk.Label(root, image=im).pack()
counter += 1
root = tk.Tk()
nextbutton = tk.Button(text="next", command=load_next_img(counter))
nextbutton.pack()
root.mainloop()
首先,它不起作用。我明白了:
---------------------------------------------------------------------------
TclError Traceback (most recent call last)
<ipython-input-24-bc9ac8d3c57e> in <module>()
14 root = tk.Tk()
15 root = tk.Toplevel()
---> 16 nextbutton = tk.Button(text="next", command=load_next_img(counter))
17 nextbutton.pack()
18
<ipython-input-24-bc9ac8d3c57e> in load_next_img(counter)
9 image_data_base64_encoded_string = df_time_text_frames["Frame_(base_64)"][counter]
10 image = tk.PhotoImage(image_data_base64_encoded_string)
---> 11 tk.Label(root, image=im).pack()
12 counter += 1
13
~\Anaconda3\lib\tkinter\__init__.py in __init__(self, master, cnf, **kw)
2761
2762 """
-> 2763 Widget.__init__(self, master, 'label', cnf, kw)
2764
2765 class Listbox(Widget, XView, YView):
~\Anaconda3\lib\tkinter\__init__.py in __init__(self, master, widgetName, cnf, kw, extra)
2294 del cnf[k]
2295 self.tk.call(
-> 2296 (widgetName, self._w) + extra + self._options(cnf))
2297 for k, v in classes:
2298 k.configure(self, v)
TclError: image "pyimage8" doesn't exist
......我想知道,如果有更容易/更好的方法吗?
编辑1:我尝试了以下内容:
import tkinter as tk
from PIL import ImageTk, Image
global counter
counter = 0
def load_next_img(counter):
#global counter
# rest of your code
counter += 1
global tk_image
image_data_base64_encoded_string = df_time_text_frames["Frame_(base_64)"][counter]
image = tk.PhotoImage(image_data_base64_encoded_string)
tk.Label(root, image=im).pack()
counter += 1
root = tk.Tk()
nextbutton = tk.Button(text="next",
command=lambda counter: load_next_image(counter))
nextbutton.pack()
root.mainloop()
我没有错误,但图像不显示。
我看到一些问题,这可能是也可能不是问题的原因。
global counter
counter = 0
def load_next_image():
global counter
# rest of your code
counter += 1
command=load_next_image(counter)
并没有做你认为它正在做的事情。 Command接受'None'或像函数一样的可调用对象。你正在做的是当创建按钮时将命令设置为等于load_next_image(counter)
的输出,这是因为load_next_image
没有返回任何内容,因此为None。
如果您不需要将任何参数传递给函数,则正确的方法是command=load_next_image
,它将命令设置为等于实际的函数句柄。单击该按钮时,将执行您的功能。
如果确实需要将参数传递给函数(有时需要),则应使用lambda
语句(请参阅this)。 nextbutton = tk.Button(text="next",
command=lambda counter: load_next_image(counter))
同样,这是有效的,因为lambda返回一个匿名函数的句柄而不是函数本身的结果。但是在你的情况下,如果你将计数器实现为像我在(1)中提到的全局变量(因为你不需要传递参数),你就不必担心这个问题。
如果可能,您可以共享指向完整源代码的链接,因为这样可以更容易地使用所有代码进行调试。
从最初的阅读中我看到了这一行。
tk.Label(root, image=im).pack()
但是im
没有在这个范围内定义。尝试用im
更改image
并检查是否再次出现错误
关于问题的第二部分:是的,可能有更好的方法来做到这一点,但我认为这超出了这个问题的范围,你可以从删除全局变量的使用开始。