Tkinter如何循环图像?

问题描述 投票:1回答:2

我有很多og base64图像存储在pandas dataframe df_time_text_frames中。现在,我想制作一个简单的程序,它向我展示图像并有一个按钮NEXT或PREVIOUS来浏览图像。

我试过了:

我定义了一个函数load_next_img,当我按下名为tk.Buttonnext时会触发该函数,然后它应该显示由全局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()

我没有错误,但图像不显示。

python tkinter
2个回答
2
投票

我看到一些问题,这可能是也可能不是问题的原因。

  1. 因为你已经全局声明了load_next_image,所以不需要将counter作为参数。删除计数器作为参数,并在函数命名空间中包含计数器,如下所示:
global counter
counter = 0
def load_next_image():
    global counter
    # rest of your code
    counter += 1
  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)中提到的全局变量(因为你不需要传递参数),你就不必担心这个问题。


0
投票

如果可能,您可以共享指向完整源代码的链接,因为这样可以更容易地使用所有代码进行调试。

从最初的阅读中我看到了这一行。

tk.Label(root, image=im).pack()

但是im没有在这个范围内定义。尝试用im更改image并检查是否再次出现错误

关于问题的第二部分:是的,可能有更好的方法来做到这一点,但我认为这超出了这个问题的范围,你可以从删除全局变量的使用开始。

© www.soinside.com 2019 - 2024. All rights reserved.