PySimpleGUI/DemoPrograms/Demo_Desktop_Widget_Digital...

186 lines
9.0 KiB
Python
Raw Normal View History

import PySimpleGUI as sg
import datetime
2021-04-01 23:14:20 +00:00
import PIL.Image, PIL.ImageTk
import random
import os
"""
Another simple Desktop Widget using PySimpleGUI
This one shows images from a folder of your choosing.
You can change the new "Standard Desktop Widget Settings"
* Theme, location, alpha channel, refresh info,
Specific to this Widget are
* Image size
* How long to show the image and if you wnt this time to vary semi-randomly
2021-04-01 23:14:20 +00:00
* Folder containing your images
Copyright 2021 PySimpleGUI
"""
ALPHA = 0.9 # Initial alpha until user changes
refresh_font = sg.user_settings_get_entry('-refresh font-', 'Courier 8')
def convert_to_bytes(file_or_bytes, resize=None):
image = PIL.Image.open(file_or_bytes)
image.thumbnail(resize)
photo_img = PIL.ImageTk.PhotoImage(image)
return photo_img
def choose_theme(location):
layout = [[sg.Text(f'Current theme {sg.theme()}')],
[sg.Listbox(values=sg.theme_list(), size=(20, 20), key='-LIST-')],
[sg.OK(), sg.Cancel()]]
event, values = sg.Window('Look and Feel Browser', layout, location=location, keep_on_top=True).read(close=True)
if event == 'OK' and values['-LIST-']:
sg.theme(values['-LIST-'][0])
sg.user_settings_set_entry('-theme-', values['-LIST-'][0])
return values['-LIST-'][0]
2021-04-01 23:14:20 +00:00
else:
return None
def make_window(location):
alpha = sg.user_settings_get_entry('-alpha-', ALPHA)
# ------------------- Window Layout -------------------
# If this is a test window (for choosing theme), then uses some extra Text Elements to display theme info
# and also enables events for the elements to make the window easy to close
2021-06-23 22:03:23 +00:00
right_click_menu = [[''], ['Choose Image Folder', 'Choose Single Image', 'Edit Me', 'Change Theme', 'Set Image Size',
'Set Time Per Image','Save Location', 'Refresh', 'Show Refresh Info', 'Hide Refresh Info', 'Alpha',
[str(x) for x in range(1, 11)], 'Exit', ]]
refresh_info = [[sg.T(size=(25, 1), font=refresh_font, k='-REFRESHED-', justification='c')],
[sg.T(size=(40,1), justification='c', font=refresh_font, k='-FOLDER-')],
[sg.T(size=(40,1), justification='c', font=refresh_font, k='-FILENAME-')]]
2021-04-01 23:14:20 +00:00
layout = [[sg.Image(k='-IMAGE-', enable_events=True)],
[sg.pin(sg.Column(refresh_info, key='-REFRESH INFO-', element_justification='c', visible=sg.user_settings_get_entry('-show refresh-', True)))]]
window = sg.Window('Photo Frame', layout, location=location, no_titlebar=True, grab_anywhere=True, margins=(0, 0), element_justification='c', element_padding=(0, 0), alpha_channel=alpha, finalize=True, right_click_menu=right_click_menu, keep_on_top=True, enable_close_attempted_event=True)
return window
def main():
loc = sg.user_settings_get_entry('-location-', (None, None))
sg.theme(sg.user_settings_get_entry('-theme-', None))
window = make_window(loc)
time_per_image = sg.user_settings_get_entry('-time per image-', 60)
vary_randomly = sg.user_settings_get_entry('-random time-', False)
width, height = sg.user_settings_get_entry('-image size-', (400,300))
image_folder = sg.user_settings_get_entry('-image_folder-', None)
try:
os.listdir(image_folder) # Try reading the folder to check to see if it is read
except:
image_folder = None
sg.user_settings_set_entry('-image_folder-', None)
2021-06-23 22:03:23 +00:00
single_image = sg.user_settings_get_entry('-single image-', None)
if image_folder is None and single_image is None:
while True:
2021-06-23 22:03:23 +00:00
images = None
image_folder = sg.popup_get_folder('Choose location of your images', location=window.current_location(), keep_on_top=True)
if image_folder is not None:
sg.user_settings_set_entry('-image_folder-', image_folder)
break
else:
if sg.popup_yes_no('No folder entered','Go you want to exit the program entirely?', keep_on_top=True) == 'Yes':
exit()
2021-06-23 22:03:23 +00:00
elif single_image is None:
images = os.listdir(image_folder)
images = [i for i in images if i.lower().endswith(('.png', '.jpg', '.gif'))]
else: # means single image is not none
images = None
while True: # Event Loop
# First update the status information
# for debugging show the last update date time
2021-06-23 22:03:23 +00:00
if single_image is None:
image_name =random.choice(images)
image_data = convert_to_bytes(os.path.join(image_folder, image_name), (width, height))
window['-FOLDER-'].update(image_folder)
else:
image_name = single_image
image_data = convert_to_bytes(single_image, (width, height))
window['-FILENAME-'].update(image_name)
2021-06-23 22:03:23 +00:00
window['-IMAGE-'].update(data=image_data)
window['-REFRESHED-'].update(datetime.datetime.now().strftime("%m/%d/%Y %I:%M:%S %p"))
# -------------- Start of normal event loop --------------
2021-06-23 22:03:23 +00:00
timeout = time_per_image * 1000 + (random.randint(int(-time_per_image * 500), int(time_per_image * 500)) if vary_randomly else 0) if single_image is None else None
event, values = window.read(timeout=timeout)
if event == sg.WIN_CLOSED:
break
elif event in (sg.WIN_CLOSE_ATTEMPTED_EVENT, 'Exit'):
sg.user_settings_set_entry('-location-', window.current_location()) # The line of code to save the position before exiting
break
if event == 'Edit Me':
sg.execute_editor(__file__)
elif event == 'Choose Image Folder':
folder = sg.popup_get_folder('Choose location of your images', default_path=image_folder, location=window.current_location(), keep_on_top=True)
if folder is not None:
image_folder = folder
window['-FOLDER-'].update(image_folder)
sg.user_settings_set_entry('-image_folder-', image_folder)
images = os.listdir(image_folder)
images = [i for i in images if i.lower().endswith(('.png', '.jpg', '.gif'))]
2021-06-23 22:03:23 +00:00
sg.user_settings_set_entry('-single image-', None)
single_image = None
elif event == 'Set Time Per Image':
layout = [[sg.T('Enter number of seconds each image should be displayed')],
[sg.I(time_per_image, size=(5,1),k='-TIME PER IMAGE-')],
[sg.CB('Use some randomness', vary_randomly, k='-RANDOM TIME-')],
[sg.Ok(), sg.Cancel()]]
event, values = sg.Window('Display duration',layout, location=window.current_location(), keep_on_top=True, no_titlebar=True ).read(close=True)
if event == 'Ok':
try:
time_per_image = int(values['-TIME PER IMAGE-'])
vary_randomly = values['-RANDOM TIME-']
sg.user_settings_set_entry('-time per image-', time_per_image)
sg.user_settings_set_entry('-random time-', values['-RANDOM TIME-'])
except:
sg.popup_error('Bad number of seconds entered', location=window.current_location(), keep_on_top=True)
elif event == 'Set Image Size':
layout = [[sg.T('Enter size should be shown at in pixels (width, height)')],
[sg.I(width, size=(4,1),k='-W-'), sg.I(height, size=(4,1),k='-H-')],
[sg.Ok(), sg.Cancel()]]
event, values = sg.Window('Image Dimensions',layout, location=window.current_location(), keep_on_top=True, no_titlebar=True ).read(close=True)
if event == 'Ok':
try:
w,h = int(values['-W-']), int(values['-H-'])
sg.user_settings_set_entry('-image size-', (w,h))
width, height = w,h
except:
sg.popup_error('Bad size specified. Use integers only', location=window.current_location(), keep_on_top=True)
elif event == 'Show Refresh Info':
window['-REFRESH INFO-'].update(visible=True)
sg.user_settings_set_entry('-show refresh-', True)
elif event == 'Save Location':
sg.user_settings_set_entry('-location-', window.current_location())
elif event == 'Hide Refresh Info':
window['-REFRESH INFO-'].update(visible=False)
sg.user_settings_set_entry('-show refresh-', False)
elif event in [str(x) for x in range(1, 11)]:
window.set_alpha(int(event) / 10)
sg.user_settings_set_entry('-alpha-', int(event) / 10)
elif event == 'Change Theme':
loc = window.current_location()
if choose_theme(loc) is not None:
window.close()
window = make_window(loc)
2021-06-23 22:03:23 +00:00
elif event == 'Choose Single Image':
single_image = sg.popup_get_file('Choose single image to show', history=True)
sg.user_settings_set_entry('-single image-', single_image)
window.close()
if __name__ == '__main__':
main()