Files
cbz/cbz/ui.py
T

96 lines
3.7 KiB
Python

from io import BytesIO
from tkinter import (Tk, Button, BOTTOM, TOP, PhotoImage, Scrollbar, X, Y, Canvas, HORIZONTAL, VERTICAL, YES, BOTH,
SUNKEN, RIGHT, LEFT, DISABLED, NORMAL, Label, Frame, ALL)
from PIL import ImageTk, Image
class ScrolledCanvas(Frame):
image_cursor: int = -2
info_text: str = ""
pages = list()
next_btn = None
prev_btn = None
counter = None
image: PhotoImage
def __init__(self, parent=None):
Frame.__init__(self, parent)
self.master.title("Spectrogram Viewer")
self.pack(expand=YES, fill=BOTH)
self.canvas = Canvas(self, relief=SUNKEN)
self.canvas.config(width=400, height=200)
self.canvas.config(highlightthickness=0)
s_bar_v = Scrollbar(self, orient=VERTICAL)
s_bar_h = Scrollbar(self, orient=HORIZONTAL)
s_bar_v.config(command=self.canvas.yview)
s_bar_h.config(command=self.canvas.xview)
self.canvas.config(yscrollcommand=s_bar_v.set)
self.canvas.config(xscrollcommand=s_bar_h.set)
s_bar_v.pack(side=RIGHT, fill=Y)
s_bar_h.pack(side=BOTTOM, fill=X)
self.canvas.pack(side=LEFT, expand=YES, fill=BOTH)
def set_text(self) -> None:
self.canvas.delete('image')
self.canvas.create_text(0, 0, anchor="nw", text=self.info_text, tags="image")
self.canvas.config(scrollregion=self.canvas.bbox(ALL))
def set_image(self, content: bytes) -> None:
self.canvas.delete('image')
with BytesIO(content) as f:
with Image.open(f) as image:
self.image = ImageTk.PhotoImage(image)
self.canvas.create_image(0, 0, anchor="nw", image=self.image, tags='image')
self.canvas.config(scrollregion=self.canvas.bbox(ALL))
def show_image(self, n: int) -> None:
self.image_cursor += n
if self.image_cursor == -1:
self.set_text()
self.prev_btn.config(state=DISABLED)
self.next_btn.config(state=NORMAL if self.pages else DISABLED)
elif self.image_cursor >= 0:
self.set_image(self.pages[self.image_cursor].content)
if self.image_cursor == len(self.pages) - 1:
self.next_btn.config(state=DISABLED)
self.prev_btn.config(state=NORMAL)
else:
self.prev_btn.config(state=NORMAL)
self.next_btn.config(state=NORMAL)
self.counter.config(text=f"{self.image_cursor + 1}/{len(self.pages)}")
self.canvas.yview_moveto(0)
self.canvas.xview_moveto(0)
def show_in_tk(title, pages, info):
root = Tk()
root.geometry("700x700")
frame = ScrolledCanvas(root)
frame.info_text = "\n".join([f"{key}: {value}" for key, value in info.items()])
frame.pages = pages
frame.pack(side=TOP)
button_frame = Frame(root)
button_next = Button(button_frame, text="Next", command=lambda: frame.show_image(1))
button_exit = Button(button_frame, text="Exit", command=root.quit)
counter = Label(button_frame)
button_prev = Button(button_frame, text="Previous", command=lambda: frame.show_image(-1))
counter.grid(row=0, column=1)
button_exit.grid(row=0, column=2)
button_next.grid(row=0, column=3)
button_prev.grid(row=0, column=0)
frame.next_btn = button_next
frame.prev_btn = button_prev
frame.counter = counter
button_frame.pack(side=BOTTOM)
root.bind('<Left>', lambda x: frame.show_image(-1) if button_prev["state"] == NORMAL else True)
root.bind('<Right>', lambda x: frame.show_image(1) if button_next["state"] == NORMAL else True)
root.bind('<Escape>', lambda x: root.quit())
frame.show_image(1)
root.title(title)
root.mainloop()