python-3.x 仅动态调整tkinter GUI中图像的大小

14ifxucb  于 2022-12-14  发布在  Python
关注(0)|答案(1)|浏览(169)

我一直在尝试创建一个带有滑块和按钮的GUI,右边有一个输出图像(不是背景图像),要求只有图像可以根据窗口大小动态地改变大小。
在我的尝试中,窗口只有在水平调整大小时才能正确显示调整大小的图像,而不是垂直调整大小。并且当窗口在垂直调整大小后更新时,它将不正确地缩放图像,导致图像的一部分被切断。
我不希望维持窗口/屏幕比率,例如:- Dynamically resize images in Tkinter
我使用的信息来自:

还有codemy的youtube视频比如How To Resize A Window Dynamically - Python Tkinter GUI Tutorial #80
获取此代码:

import tkinter as tk
from tkinter import *
from tkinter.filedialog import askopenfilename
from PIL import ImageTk, Image

def show_values():
    print(slider1.get())

window = tk.Tk()

filename = askopenfilename()  # show an "Open" dialog box and return the path to the selected file

image = ImageTk.PhotoImage(Image.open(filename))
imageWidth = image.width()
imageHeight = image.height()

canvas = Canvas(window, width=imageWidth, height=imageHeight)
canvas.pack(fill=BOTH, expand=True, side=RIGHT)
canvas.create_image(0, 0, image=image, anchor='nw')

slider1 = Scale(window, from_=0, to=42, orient='vertical')
slider1.pack(side=LEFT)

def resizer(e):
    global image1, resized_image, new_image
    image1 = Image.open(filename)
    resized_image = image1.resize((e.width, e.height), Image.Resampling.LANCZOS)
    new_image = ImageTk.PhotoImage(resized_image)
    canvas.create_image(0, 0, image=new_image, anchor='nw')

window.bind('<Configure>', resizer)

Button(window, text='Process Image', command=show_values).pack(side=BOTTOM)

window.mainloop()

字符串
我也尝试过使用加权网格和NSEW(N+S+E+W)方法,但都没有成功。

vktxenjb

vktxenjb1#

当你绑定到一个根窗口时,这个绑定会被应用到所有的小部件上,这是因为绑定被应用到绑定 * 标签 * 上,并且根窗口的标签会被添加到每个小部件的绑定标签列表中。
因此,每次窗口改变大小时,resizer会被调用一次,用于根窗口,另一次用于画布,这意味着e.widthe.height会有所不同,因为有时它指的是窗口的宽度,有时指的是画布的宽度。
简单的解决方案是只绑定到画布的<Configure>事件,如果您正确地配置了画布,使其在窗口调整大小时调整大小,那么这一切都将正常工作。
另外,你不应该在画布上创建新的图像对象,你只是把一个图像堆叠在另一个图像上,你的程序最终会因为图像的数量过多而崩溃。
相反,您可以重新配置现有的图像对象以使用新的小部件。

...
image_id = canvas.create_image(0, 0, image=image, anchor='nw')
...
def resizer(e):
    global image1, resized_image, new_image
    image1 = Image.open(filename)
    resized_image = image1.resize((e.width, e.height), Image.Resampling.LANCZOS)
    new_image = ImageTk.PhotoImage(resized_image)
    canvas.itemconfigure(image_id, image=new_image)

canvas.bind('<Configure>', resizer)
...

相关问题