Before design a script for PNG viewer and selector, some steps for window layout considered.
from io import BytesIO
from pathlib import Path
from PIL import Image
import PySimpleGUI as sg
def move_center(window):
screen_width, screen_height = window.get_screen_dimensions()
win_width, win_height = window.size
x, y = (screen_width - win_width)//2, (screen_height - win_height)//2
window.move(x, y)
def resize(file, new_size):
try:
im = Image.open(file)
w, h = im.size
if w >= h:
size = (new_size, int(new_size/w*h))
else:
size = (int(new_size/h*w), new_size)
new_im = im.resize(size) # , Image.ANTIALIAS
with BytesIO() as buffer:
new_im.save(buffer, format="PNG")
data = buffer.getvalue()
except:
data = None
return data
def new_window(directory=''):
path = Path(directory)
if directory and path.is_dir():
files = list(map(lambda file:str(file), path.glob(pattern)))
else:
files = []
if files:
layout_thumbnail = []
row = []
length = len(files)
size = (thumbnail_width, thumbnail_width)
for i, file in enumerate(files):
data = resize(file, thumbnail_width)
if (i % columns) == 0:
pad = ((0, gap), gap)
elif (i % columns) == columns - 1:
pad = ((gap, gap*2), gap)
else:
pad = (gap, gap)
frame = sg.Frame("",
[[sg.Image(data=data, size=size, pad=(gap, gap),
key=("Thumbnail", i), metadata=False)]],
pad=pad, background_color=sg.theme_background_color(),
key=("Thumbnail_Frame", i))
row.append(frame)
if (i % columns) == columns-1 or i == length - 1:
layout_thumbnail.append(row)
row = []
else:
layout_thumbnail = [[]]
width = (thumbnail_width + 4*gap + 4) * columns + 2*gap + 16
height = (thumbnail_width + 4*gap + 4) * columns
layout_thumbnail_frame = [
[sg.Column(layout_thumbnail, expand_x=True, expand_y=True,
scrollable=True, vertical_scroll_only=True, pad=(0, 0))],
]
layout_left_frame = [
[sg.Input(directory, size=10, disabled=True, expand_x=True, key='Directory'),
sg.Button('Browse')],
[sg.Frame("", layout_thumbnail_frame, size=(width, height), border_width=0)],
[sg.Listbox(selected_files, size=(10, 5), expand_x=True, key='Select_Files')],
]
layout_right_frame = [
[sg.Image(expand_x=True, expand_y=True, key='View')],
]
layout = [
[sg.Frame('', layout_left_frame),
sg.Frame('', layout_right_frame, size=(10, 10), expand_y=True, key='Right Frame')],
]
window = sg.Window('PNG Thumbnail Viewer', layout, alpha_channel=0, finalize=True)
w, h = window['Right Frame'].get_size()
window['Right Frame'].set_size((h, h))
window.refresh()
move_center(window)
window.set_alpha(1)
for key, element in window.key_dict.items():
if isinstance(key, tuple) and key[0]=='Thumbnail':
element.bind("<Control-Button-1>", "Control")
element.bind("<Button-1>", "B1")
return window, h, files, []
font = ("Courier New", 11)
sg.theme('DarkBlue3')
sg.set_options(font=font, dpi_awareness=True)
gap = 3
columns = 6
directory = ''
thumbnail_width = 90
selected_files = []
default_root = 'D:/'
pattern = '*.png'
bg = {True:'yellow', False:sg.theme_background_color()}
window, view_width, files, selected_files = new_window(default_root)
while True:
event, values = window.read()
if event == sg.WINDOW_CLOSED:
break
elif event == 'Browse':
directory = sg.popup_get_folder('', no_window=True)
if directory:
new_win = new_window(directory)
window.close()
window, view_width, files, selected_files = new_win
window['Select_Files'].update(values=[])
elif isinstance(event, tuple) and len(event)==2:
(element, index), bind = event
if bind == 'B1':
data = resize(files[index], view_width)
window['View'].update(data=data)
elif bind == 'Control':
elem = window[event[0]]
border = elem.metadata = not elem.metadata
window[("Thumbnail_Frame", index)].Widget.configure(bg=bg[border])
if border:
selected_files.append(files[index])
else:
selected_files.remove(files[index])
window['Select_Files'].update(values=selected_files)
window.close()
Before design a script for PNG viewer and selector, some steps for window layout considered.
'<Control-Button-1>''<Button-1>'on thumbnail.