Initial commit

This commit is contained in:
2024-03-24 20:09:46 +01:00
commit f836e7c7ba
10 changed files with 1670 additions and 0 deletions

151
app/preview.py Executable file
View File

@ -0,0 +1,151 @@
import tkinter as tk
from dataclasses import dataclass
import ttkbootstrap as ttk
from PIL import Image, ImageTk
from ttkbootstrap.scrolled import ScrolledFrame
class Slide(tk.Frame):
def __init__(self, preview, image: Image.Image):
super().__init__(preview._frame)
self.preview = preview
self.image = image
self.imagetk = ImageTk.PhotoImage(image)
self.label = tk.Label(self, image=self.imagetk, borderwidth=1, relief=tk.SOLID)
self.label.pack(fill=tk.X, pady=(0, 5))
self.delbutton = ttk.Button(self, text="Löschen", bootstyle="danger-outline", command=self._on_delete)
self.delbutton.pack(fill=tk.X)
self._is_selected = False
self.highlight = None
self._configure_id = None
self.bind("<Configure>", self._on_resize)
self.label.bind("<Button-1>", self._on_select)
def _on_resize(self, e: tk.Event):
if self._configure_id != None:
self.after_cancel(self._configure_id)
self._configure_id = self.after(100, self._on_final_resize)
def _on_select(self, e: tk.Event):
if self._is_selected:
self._on_unselect()
else:
self._is_selected = True
self.highlight = tk.Label(self, text="Ausgewählt", bg="green")
self.highlight.place(x=0, y=0)
self.preview.notify_selection(self)
def _on_unselect(self):
self._is_selected = False
if self.highlight is not None:
self.highlight.destroy()
def _on_final_resize(self):
thumbnail = self.image.copy()
thumbnail.thumbnail(size=(self.winfo_width(), self.image.height), resample=Image.NEAREST)
self.imagetk = ImageTk.PhotoImage(thumbnail)
self.label.configure(image=self.imagetk)
self._configure_id = None
def _on_delete(self):
self.preview.remove(self)
class SlidePreview(ScrolledFrame):
def __init__(self, parent, *args, columns: int = 4, **kwargs):
super().__init__(parent, *args, **kwargs)
self._frame = tk.Frame(self)
self._frame.pack(fill=tk.BOTH, expand=True)
self.columns = columns
for column in range(columns):
self._frame.grid_columnconfigure(column, weight=1)
self._selected_index = -1
self._slides = []
def _on_resize(self, e: tk.Event):
slide = self._slides[0]
slide.grid_forget()
slide.grid(row=0, column=0, sticky=tk.EW)
def notify_selection(self, selected: Slide):
self._selected_index = self._slides.index(selected)
for slide in self._slides:
if slide is not selected:
slide._on_unselect()
def notify_unselected(self, unselected: Slide):
if self._slides.index(unselected) == self._selected_index:
self._selected_index = -1
def add(self, slide: Image.Image):
index = len(self._slides)
s = Slide(self, slide)
s.grid(row=index // self.columns, column=index % self.columns, sticky=tk.NSEW, padx=10, pady=10)
self._slides.append(s)
def insert(self, slide: Image.Image, index: int):
s = Slide(self, slide)
self._slides.insert(index, s)
for index, slide in enumerate(self._slides):
slide.grid_forget()
slide.grid(row=index // self.columns, column=index % self.columns, sticky=tk.NSEW, padx=10, pady=10)
slide._on_final_resize()
if index <= self._selected_index:
self._selected_index += 1
def remove(self, slide: Slide):
index = self._slides.index(slide)
if index < 0:
return
if index == self._selected_index:
self._selected_index = -1
elif index < self._selected_index:
self._selected_index -= 1
slide.destroy()
del self._slides[index]
for index, slide in enumerate(self._slides[index:], start=index):
slide.grid_forget()
slide.grid(row=index // self.columns, column=index % self.columns, sticky=tk.NSEW, padx=10, pady=10)
def clear(self):
for slide in self._slides:
slide.destroy()
self._slides = []
self._selected_index = -1
def __len__(self):
return len(self._slides)
def get_images(self) -> list[Image.Image]:
return [slide.image for slide in self._slides]
if __name__ == "__main__":
main = tk.Tk()
main.geometry("800x400")
sp = SlidePreview(main)
sp.pack(fill=tk.BOTH, expand=True)
for filename in [f"{i:02}" for i in range(16)]:
img = Image.open(f"machine learning in der radiologie_5ebbrbz/{filename}.png")
sp.add(img)
main.mainloop()