0

这是我使用 tkinter 的第一天,我想知道如何正确编码我所做的事情。

我想做的是一种立体模型,所以我想找到一种在画布上显示图片的方法,并且有两个按钮,这样我就可以转到上一张或下一张。我存储图片的方式是使用lnumpy 数组的列表l,大小为n,所以我有n图片,它们的大小相同。所以我写了以下代码:

from tkinter import *
import numpy as np
from PIL import Image, ImageTk


import sys
sys.setrecursionlimit(10000) #I increased the recursion limit because I had some issues

l = [(255*np.random.rand(50,50)).astype(np.uint8) for i in range(105)] #this is a random list in case you want to test the code

def next(i,n):
    if i == n-1:
        return 0
    else:
        return i+1

def previous(i,n):
    if i==0:
        return n-1
    else:
        return i-1



window = Tk()
window.geometry("200x100+900+500")

def display(i):
    
    #This is to clear my window at each iteration because I would like to keep the same window

    for widget in window.winfo_children():
        widget.destroy()

    array = l[i] #this is the i-th picture

    img =  ImageTk.PhotoImage(image=Image.fromarray(array),master = window)

    canvas = Canvas(window, width=48, height=48)
    canvas.place(x=10, y=20)
    canvas.create_image(0,0, anchor="nw", image=img)

    Label(window, text="Picture n°"+str(i), fg="black").place(x=5, y=0)

    Button(window, text ='Next',command=lambda: display(next(i,len(l)))).place(x=140, y=35)
    Button(window, text ='Previous',command = lambda: display(previous(i,len(l)))).place(x=70, y=35)
    window.mainloop()


display(0) 

我知道这是糟糕的代码,而不是应该写的方式。它工作正常,但我需要帮助来改进代码。

4

1 回答 1

1

你应该只把更新图像的代码放在里面display(),在函数外面创建接口。那么就不需要递归了。

还需要一个全局变量来跟踪图像列表的当前索引。Next单击或Previous按钮时,应更新此变量。

下面是一个修改过的例子:

from tkinter import *
import numpy as np
from PIL import Image, ImageTk

l = [(255*np.random.rand(50,50)).astype(np.uint8) for i in range(105)] #this is a random list in case you want to test the code
current = 0

def display(dir):
    global current
    # update "current" based on "dir"
    current = (current + dir) % len(l)
    # show the "current" image
    image = ImageTk.PhotoImage(Image.fromarray(l[current]))
    imgbox.config(image=image, text=f"Picture n°{current}")
    imgbox.image = image  # keep a reference to avoid "image" from being garbage collected

window = Tk()
window.geometry("200x100+900+500")

# use a label for showing image and text together
imgbox = Label(window, fg="black", compound="bottom", width=70)
imgbox.place(x=5, y=0)

Button(window, text ='Next', command=lambda: display(+1)).place(x=150, y=35)
Button(window, text ='Previous', command=lambda: display(-1)).place(x=80, y=35)

display(0) # show first image
window.mainloop()
于 2020-12-29T15:57:37.347 回答