在不破坏 tkinter 布局的情况下调整图像大小

Resize an image without breaking the layout in tkinter

好的,所以我有一个问题,并且尝试了太长时间来解决它。我不知道如何在不破坏布局的情况下调整图像大小。在情况 (1) 中,它填满了整个 space,从而破坏了我的布局,我认为这是因为我在绑定到 <Configure> 事件的函数中调用了 configure 函数。在情况 (2) 中,我可以调整图像大小,但我在缩放后的图像周围有一个巨大的边框,这会破坏布局。我什至尝试使用 Canvas 而不是 Label,但仅绘制 Canvas 会破坏布局,因为它占用了太多 space 并将所有内容向右移动。

想法如何解决?

from tkinter import *
from PIL import ImageTk, Image

global image_label, image_ref

def main():
    global image_label
    root = Tk()
    root.geometry("600x400")

    root.grid_rowconfigure(0, weight=1)
    root.grid_columnconfigure(0, weight=1)
    content_frame = Frame(root, bg="#FF0000")
    content_frame.grid(row=0, column=0, sticky="news")

    column_ratio = [10,25,10,45,10]
    row_ratio = [10,80,10]
    for col_idx in range(5):
        content_frame.grid_columnconfigure(col_idx, weight=column_ratio[col_idx])
    for row_idx in range(3):
        content_frame.grid_rowconfigure(row_idx, weight=row_ratio[row_idx])

    image_label = Label(content_frame, bg="#00FF00")
    image_label.grid(row=1, column=1, sticky="news")
    #image_label.bind("<Configure>", resize_configure)  # <--- (1)

    second_label = Label(content_frame, bg="#0000FF", text="Label on the right")
    second_label.grid(row=1, column=3, sticky="news")
    second_label.bind("<Button-1>", resize_click)       # <--- (2)


    root.mainloop()

def resize(size, label):
    global image_ref
    image = Image.open("test.png").resize(size, Image.ANTIALIAS)
    image_ref = ImageTk.PhotoImage(image)
    label.configure(image=image_ref)

def resize_configure(event):
    global image_label
    size = (event.width, event.height)
    resize(size, image_label)

def resize_click(event):
    global image_label
    image_label.update()
    size = (image_label.winfo_width(), image_label.winfo_height())
    resize(size, image_label)



if __name__ == "__main__":
    main()

Case 1 as an image

Case 2 as an image

How it should look like

您可以使用 place() 而不是 grid():

import tkinter as tk
from PIL import Image, ImageTk

base_img = Image.open('test.png')

def on_label_resize(event):
    lbl = event.widget
    img = ImageTk.PhotoImage(base_img.resize((event.width, event.height)))
    lbl.config(image=img)
    lbl.image = img

def main():
    root = tk.Tk()
    root.geometry('640x400')

    img_lbl = tk.Label(root, image=None, bg='#00ff00')
    img_lbl.place(relx=.1, rely=.1, relwidth=.25, relheight=.8)
    img_lbl.bind('<Configure>', on_label_resize)

    txt_lbl = tk.Label(root, text='Label on the right', bg='#0000ff')
    txt_lbl.place(relx=.45, rely=.1, relwidth=.45, relheight=.8)

    root.mainloop()

if __name__ == '__main__':
    main()