New Demo - Desktop Widget (aka Rainmeter) Digital Picture Frame
This commit is contained in:
parent
2085a6ec3b
commit
78e41a8fcf
|
@ -0,0 +1,178 @@
|
|||
import PySimpleGUI as sg
|
||||
import sys
|
||||
import datetime
|
||||
import PIL, PIL.Image, PIL.ImageTk
|
||||
import random
|
||||
import os
|
||||
import io
|
||||
|
||||
"""
|
||||
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
|
||||
* Folder containing your image
|
||||
|
||||
|
||||
Copyright 2021 PySimpleGUI
|
||||
"""
|
||||
|
||||
ALPHA = 0.9 # Initial alpha until user changes
|
||||
THEME = 'Dark green 3' # Initial theme until user changes
|
||||
refresh_font = sg.user_settings_get_entry('-refresh font-', 'Courier 8')
|
||||
|
||||
# May add ability to change theme from the user interface. For now forcing to constant
|
||||
|
||||
UPDATE_FREQUENCY_MILLISECONDS = 1000 * 60 * 60 # update every hour
|
||||
|
||||
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]
|
||||
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
|
||||
right_click_menu = [[''], ['Choose Image Folder', '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-')]]
|
||||
|
||||
main_layout = [[sg.Image(k='-IMAGE-', enable_events=True)]]
|
||||
|
||||
layout = main_layout + \
|
||||
[[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)
|
||||
|
||||
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)
|
||||
|
||||
if image_folder is None:
|
||||
while True:
|
||||
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()
|
||||
images = os.listdir(image_folder)
|
||||
images = [i for i in images if i.lower().endswith(('.png', '.jpg', '.gif'))]
|
||||
while True: # Event Loop
|
||||
# First update the status information
|
||||
# for debugging show the last update date time
|
||||
image_name =random.choice(images)
|
||||
image_data = convert_to_bytes(os.path.join(image_folder, image_name), (width, height))
|
||||
window['-IMAGE-'].update(data=image_data)
|
||||
window['-FOLDER-'].update(image_folder)
|
||||
window['-FILENAME-'].update(image_name)
|
||||
print(f'showing {image_name}')
|
||||
window['-REFRESHED-'].update(datetime.datetime.now().strftime("%m/%d/%Y %I:%M:%S %p"))
|
||||
# -------------- Start of normal event loop --------------
|
||||
timeout = time_per_image * 1000 + (random.randint(int(-time_per_image * 500), int(time_per_image * 500)) if vary_randomly else 0)
|
||||
event, values = window.read(timeout=timeout)
|
||||
print(event, values)
|
||||
if event == sg.WIN_CLOSED or event == 'Exit':
|
||||
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'))]
|
||||
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)
|
||||
|
||||
window.close()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
Loading…
Reference in New Issue