【问题标题】:How to properly use buttons in tkinter with same window如何在具有相同窗口的 tkinter 中正确使用按钮
【发布时间】:2020-12-29 14:18:13
【问题描述】:

这是我使用 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) 

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

【问题讨论】:

  • @JacksonPro 我无法在代码中定义l,因为它是我之前导入的图片列表。但是您可以以l = [(255*np.random.rand(50,50)).astype(np.uint8) for i in range(105)] 为例。我编辑了代码。

标签: python tkinter tkinter-button


【解决方案1】:

您应该只将更新图像的代码放在display() 中,并在函数之外创建接口。那么就不需要递归了。

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

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

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()

【讨论】:

  • 非常感谢!它工作得非常好,我再也没有问题了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-06
  • 1970-01-01
  • 2021-03-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多