MCPcopy Create free account
hub / github.com/PaulleDemon/PyUIBuilder / ImageLabel

Class ImageLabel

src/frameworks/tkinter/pythonWidgets/imageLabel.py:11–92  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

9
10
11class ImageLabel(tk.Label):
12 def __init__(self, master, image_path=None, mode="cover", width=100, height=100, *args, **kwargs):
13 """
14 mode:
15 - "fit" -> Keeps aspect ratio, fits inside label
16 - "cover" -> Covers label fully, cropping excess
17 """
18 super().__init__(master, width=width, height=height, *args, **kwargs)
19 self.parent = master
20 self.image_path = image_path
21 self.mode = mode
22 self.original_image = None
23 self.photo = None
24 self.resize_job = None # Debounce job reference
25
26 if mode not in ['fit', 'cover']:
27 raise Exception("Mode can only be fit or cover.")
28
29 if image_path:
30 try:
31 self.original_image = Image.open(image_path)
32 self.photo = ImageTk.PhotoImage(self.original_image)
33 self.config(image=self.photo)
34
35 self.force_resize()
36 except Exception as e:
37 print(f"Error loading image: {e}")
38
39 self.after(100, self.init_events)
40
41 def init_events(self):
42 self.parent.bind("<Configure>", self.on_resize)
43
44 def on_resize(self, event=None):
45 """Debounce resizing to prevent rapid execution."""
46 if self.resize_job:
47 self.after_cancel(self.resize_job)
48 self.resize_job = self.after(1, self.force_resize) # Debounce
49
50 def force_resize(self):
51 """Resize image using actual widget size."""
52
53 if self.original_image is None:
54 return # Do nothing if no image is loaded
55
56 width = self.winfo_width()
57 height = self.winfo_height()
58
59 if width < 5 or height < 5:
60 return
61
62 aspect_ratio = self.original_image.width / self.original_image.height
63
64 if self.mode == "fit":
65 if width / height > aspect_ratio:
66 new_width = int(height * aspect_ratio)
67 new_height = height
68 else:

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected