Хорошо, после некоторого тестирования, я думаю, что нашел решение, которое вы ищете.
Вместо того, чтобы размещать метку на холсте, мы можем поместить метку в рамку и затем изменить ее размер, чтобы он соответствовал холсту.размер.В то же время мы можем изменить размер изображения в метке, и даже если оно будет немного больше рамки, оно будет вызывать другое изменение размера, пока вы не измените размер окна напрямую.
import tkinter as tk
from PIL import Image, ImageTk
root = tk.Tk()
canvas = tk.Canvas(root, height=500, width=500)
canvas.pack(fill='both', expand=True)
frame = tk.Frame(canvas)
canvas.create_window((0, 0), anchor='nw', window=frame, tags='my_frame')
def resize_image(event):
canvas.itemconfigure("my_frame", width=event.width, height=event.height)
image = copy_of_image.resize((event.width, event.height ))
photo = ImageTk.PhotoImage(image)
label.configure(image=photo)
label.image = photo
image = Image.open("*file path to image*")
copy_of_image = image.copy()
photo = ImageTk.PhotoImage(image)
label = tk.Label(frame, image=photo)
label.pack(fill='both', expand=True)
canvas.bind('<Configure>', resize_image)
root.mainloop()
Для решения ООП см. Ниже:
import tkinter as tk
from PIL import Image, ImageTk
class App(tk.Tk):
def __init__(self):
super().__init__()
self.canvas = tk.Canvas(self)
self.frame = tk.Frame(self.canvas)
self.canvas.pack(fill='both', expand=True)
image = Image.open('./Images/green.png')
self.copy_of_image = image.copy()
photo = ImageTk.PhotoImage(image)
self.label = tk.Label(self.frame, image=photo)
self.label.pack(fill='both', expand=True)
self.label.image = photo
self.canvas.create_window((0, 0), anchor='nw', window=self.frame, tags='my_frame')
self.canvas.bind("<Configure>", self.on_canvas_configure)
def on_canvas_configure(self, event):
self.canvas.itemconfigure("my_frame", width=event.width, height=event.height)
image = self.copy_of_image.resize((event.width, event.height))
photo = ImageTk.PhotoImage(image)
self.label.configure(image=photo)
self.label.image = photo
if __name__ == "__main__":
App().mainloop()