python pysimpleGUI changing keep on Top - python

I have a couple programs I am trying this on here is a smaller one. I have a right click set up I want to change keep_on_top=True to keep_on_top=False
as you can see I am able to change the Alpha level but not able to figure out how to make this change here is the code of a simple local and Zulu time clock
import PySimpleGUI as sg
import pytz
from datetime import datetime
Cur_Time_Date=''
Cur_Time_DateUTC=''
ALPHA = 0.9 # Initial alpha until user changes
def update_window():
current_datetime = datetime.now()
Cur_Time_Date = current_datetime.strftime("%H:%M:%S (L) %m/%d/%y")
utc_time = datetime.now(pytz.utc)
Cur_Time_DateUTC = utc_time.strftime("%H:%M:%S (Z) %m/%d/%y")
window['-LCL-'].update(Cur_Time_Date + '(L)')
window['-UTC-'].update(Cur_Time_DateUTC + '(Z)')
def create_window():
right_click_menu = [[''],['keep_on_top', 'Alpha', [str(x) for x in range(1, 11)], 'Exit', ]]
layout = [
[sg.Text(Cur_Time_Date, key = '-LCL-')],
[sg.Text(Cur_Time_DateUTC, key = '-UTC-')]
]
return sg.Window('Local/UTC time', layout, alpha_channel=ALPHA, no_titlebar=True, grab_anywhere=True, right_click_menu=right_click_menu, keep_on_top=True)
window = create_window()
while True:
event, values = window.read(timeout=1000)
if event in (sg.WIN_CLOSED, '-CLOSE-'):
break
elif event in (sg.WIN_CLOSE_ATTEMPTED_EVENT, 'Exit'):
break
elif event == 'keep_on_top':
sg.popup( title = 'Keep On Top', keep_on_top=True)
elif event in [str(x) for x in range(1, 11)]:
window.set_alpha(int(event) / 10)
#window.close
update_window()

I figured it out if anyone else is looking
First, I set the variable and setup my own popup box:
keepOnTop = True
def My_popup():
layout = [[sg.Text('Keep On Top')],
[sg.Push(), sg.Yes(),sg.No(), sg.Push()]]
window = sg.Window('', layout, keep_on_top=True)
event, values = window.read()
window.close()
return (event)
I set the variable to start and used it to set at the beginning.
Then I used this when selecting option from right clicking
elif event == 'keep_on_top':
ans=My_popup()
print(ans)
if ans == 'Yes':
keepOnTop=True
else:
keepOnTop=False
print(keepOnTop)
window.close()
window = create_window()
I also needed to add, finalize=True to the window

Related

How to control Progress bar size PySimpleGUI

I want to create a progress bar using PySimpleGUI but I want the user to put the maximum of the progress bar.
this is my code:
import PySimpleGUI as sg
import random, time
sg.theme("LightBlue")
progress_value=input()
layout = [[sg.Text("Enter a number out of 50", font='Lucida'),
sg.InputText(key='-PROGRESS_VALUE-', font='Lucida, 20', size=(20, 40))],
[sg.ProgressBar(progress_value, orientation='h', size=(100, 20), border_width=4, key='-PROGRESS_BAR-',
bar_color=("Blue", "Yellow"))],
[sg.Button('Change Progress'), sg.Exit(),sg.Button('Stop Progress')]]
window = sg.Window("Progress Bar", layout)
while True:
event, values = window.read()
if event == 'Exit' or event == sg.WIN_CLOSED:
break
progress_value = int(values['-PROGRESS_VALUE-'])
if event == "Change Progress":
for i in range(progress_value):
event, values = window.read(1000)
if event == "Stop Progress":
window['-PROGRESS_BAR-'].update(i-1)
break
window['-PROGRESS_BAR-'].update(max=progress_value)
window['-PROGRESS_BAR-'].update(i+1)
window.close()
as you can see the maximum which is "progress_value" is given by an input (progress_value=input())
but i want it to come from the input text of the user (sg.InputText(key='-PROGRESS_VALUE-', font='Lucida, 20', size=(20, 40))) and that value will be set to progress_value
Here's one way of doing what you're after using a single event loop
When changing the max value of a ProgressBar, you must set a current value too (in the same update call).
import PySimpleGUI as sg
sg.theme("LightBlue")
progress_value = 50
layout = [[sg.Text("Enter a number out of 50", font='Lucida'),
sg.InputText(key='-PROGRESS_VALUE-', font='Lucida, 20', size=(20, 40))],
[sg.ProgressBar(progress_value, orientation='h', size=(100, 20), border_width=4, key='-PROGRESS_BAR-',
bar_color=("Blue", "Yellow"))],
[sg.Button('Change Progress'), sg.Button('Start Progress'), sg.Button('Stop Progress')]]
window = sg.Window("Progress Bar", layout)
progress_started, counter, timeout = False, 0, None
while True:
event, values = window.read(timeout=timeout)
if event == 'Exit' or event == sg.WIN_CLOSED:
break
if event == "Change Progress":
progress_value = int(values['-PROGRESS_VALUE-'])
# NOTE - must set a current count when changing the max value
window['-PROGRESS_BAR-'].update(current_count= 0, max=progress_value)
elif event == 'Start Progress':
progress_started = True
counter = 0
timeout = 1000
elif event == 'Stop Progress':
progress_started = False
timeout = None
if progress_started:
window['-PROGRESS_BAR-'].update(counter)
counter += 1
if counter > progress_value:
progress_started = False
window.close()

How do I utilize multiprocessing module in Python?

I'm trying to add an alarm sound to my timer program, however whenever the function for the sound gets called, the program times out, and you have to wait until the sound file finishes. I've tried using asyncio and right now I'm trying to use multiprocessing modules to resolve this issue, however I've kept on hitting my head against a brick wall.
Here is my code right now for the program
import PySimpleGUI as sg
import time
from pydub import AudioSegment
from pydub.playback import play
import multiprocessing
duration = 500 # milliseconds
freq = 440 # Hz
sg.theme('DarkBrown4')
song = AudioSegment.from_mp3("alarm.mp3")
quiet_song = song - 40
def sound():
play(quiet_song)
def main():
centered_column = [[sg.T(('Set Time to Study'), font=('Consolas', 20))],
[sg.T((''), font=('Consolas', 20), key='countdown')],
[sg.B('Exit'),
sg.B('Start/Stop')], # Buttons For Timer
[sg.B('Pomodoro'),
sg.B('Short Break'),
sg.B('Long Break')
]]
layout = [[sg.Text(key='-EXPAND-', font='ANY 1', pad=(0, 0))], # the thing that expands from top
[sg.Text('', pad=(0, 0), key='-EXPAND2-'), # the thing that expands from left
sg.Column(centered_column, vertical_alignment='center', justification='center', k='-C-')]]
window = sg.Window('StudyWare Timer', layout, size=(400, 200), grab_anywhere=True, resizable=True, finalize=True)
window['-C-'].expand(True, True, True)
window['-EXPAND-'].expand(True, True, True)
window['-EXPAND2-'].expand(True, False, True)
active = False
value = 0
while True:
event, values = window.Read(timeout=1000)
# print(event, values)
if event == sg.WIN_CLOSED or event == 'Exit':
break
m, s = divmod(value, 60)
timerx = "%02d:%02d" % (m, s)
if event == 'Pomodoro':
# active = not active
value = 1
window.Element('countdown').Update(value=timerx)
if event == 'Short Break':
# active = not active
value = 300
window.Element('countdown').Update(value=timerx)
if event == 'Long Break':
# active = not active
value = 900
window.Element('countdown').Update(value=timerx)
if event == 'Start/Stop':
active = not active
if event == '__TIMEOUT__' and active:
window.Element('countdown').Update(value=timerx)
value -= 1
if value == -1:
active = not active
window.refresh()
if __name__ == '__main__':
p2 = multiprocessing.Process(target=main())
p = multiprocessing.Process(target=sound())
p2.start()
p.start()
p2.join()
p.join()
Any suggestions would be greatly appreciated! )))

Can I display prints using PySimpleGUI?

I am using PySimpleGUI to build a GUI for my application. I am trying to print out on screen some messages for the user through a Listbox but when I call the window[].update() lines the print out is not showing by line but putting each character on a new line. I am not sure if Listbox is the function that I should be using or if there is another function better suited for what I want to do.
import PySimpleGUI as sg
import os, sys
file_list_column = [
[sg.Text('File Name: '), sg.In(size = (25, 1), enable_events = True, key = '-ID-')],
[sg.Text('File Location: '), sg.In(size = (25, 1), enable_events = True, key = '-FOLDER-'),sg.FolderBrowse()],
[sg.Button('Create Location')],
[sg.Listbox(values = [], enable_events = True, size = (40, 20), key = '-UPDATES-')],]
layout = [[sg.Column(file_list_column)],
[sg.Button('Close')]]
window = sg.Window('Test', layout)
while True:
event, values = window.read()
if event == 'Close' or event == sg.WIN_CLOSED or event == 'Exit':
break
if event == 'Create Location':
try:
os.makedirs(os.path.join(values['-FOLDER-'], values['-ID-']))
window['-UPDATES-'].update(str('Folder location created.'))
except:
window['-UPDATES-'].update(str('Folder location NOT created.'))
window.close()
The string I want to display to the user is placing each character on its own line.

PySimpleGUI changing visibility breaks columns(?)

I have 2 columns and I want to reveal them on a button press by using the visibility parameter. However, it seems that columns that go from invisible to visible stop being next to each other and are instead arranged like rows.
Here is the code without the reveal, and the columns work fine:
import PySimpleGUI as sg
left_col = sg.Column([[sg.Frame('',[],background_color = '#FF0000',size = (60,40))]])
right_col = sg.Column([[sg.Frame('',[],background_color = '#00FF00',size = (60,40))]])
layout = [
[sg.Button('reveal')],
[left_col,right_col]]
window = sg.Window('Converter', layout)
while True:
event, values = window.read()
if event == sg.WIN_CLOSED:
break
window.close()
And here is the same code with the columns being revealed:
import PySimpleGUI as sg
left_col = sg.Column([[sg.Frame('',[],background_color = '#FF0000',size = (60,40))]],visible = False, key = 'left')
right_col = sg.Column([[sg.Frame('',[],background_color = '#00FF00',size = (60,40))]],visible = False, key = 'right')
layout = [
[sg.Button('reveal')],
[left_col,right_col]]
window = sg.Window('Converter', layout)
while True:
event, values = window.read()
if event == sg.WIN_CLOSED:
break
if event == 'reveal':
window['left'].update(visible = True)
window['right'].update(visible = True)
window.close()
I guess my question is whether there is a workaround for this (or whether I did something wrong).
Elements after visible=False will miss it's location in the window, so use function pin to keep the location for element if you want to set it to be invisible.
layout = [
[sg.Button('reveal')],
[sg.pin(left_col), sg.pin(right_col)]]
By default, the background is the background color of theme. Of course, you can built one by yourself which with one more option bg as background_color.
Don't forget to set the background color of the Column in your layout at the same time.
def pin(elem, vertical_alignment=None, shrink=True, expand_x=None, expand_y=None, bg=None):
if shrink:
return sg.Column([[elem, sg.Column([[]], pad=(0,0), background_color=bg)]], background_color=bg, pad=(0, 0), vertical_alignment=vertical_alignment, expand_x=expand_x, expand_y=expand_y)
else:
return sg.Column([[elem]], pad=(0, 0), vertical_alignment=vertical_alignment, expand_x=expand_x, expand_y=expand_y, background_color=bg)
Then you code maybe something like this
import PySimpleGUI as sg
def pin(elem, vertical_alignment=None, shrink=True, expand_x=None, expand_y=None, bg=None):
if shrink:
return sg.Column([[elem, sg.Column([[]], pad=(0,0), background_color=bg)]], background_color=bg, pad=(0, 0), vertical_alignment=vertical_alignment, expand_x=expand_x, expand_y=expand_y)
else:
return sg.Column([[elem]], pad=(0, 0), vertical_alignment=vertical_alignment, expand_x=expand_x, expand_y=expand_y, background_color=bg)
left_col = sg.Column([[sg.Frame('', [], background_color = '#FF0000', size = (60,40))]], background_color='blue')
right_col = sg.Column([[sg.Frame('', [], background_color = '#00FF00', size = (60,40))]], background_color='blue')
layout = [
[sg.Button('reveal')],
[pin(left_col, bg='blue'), pin(right_col, bg='blue')]]
window = sg.Window('Converter', layout, background_color='blue')
while True:
event, values = window.read()
if event == sg.WIN_CLOSED:
break
window.close()

comment a line of code if checkbox checked Pysimplegui

how can i comment/uncomment a line of code by checking and unchecking a checkbox in python with PySimpleGUI?
also i don't know if i wrote the code in correct way but i'm just trying to comment a line of code by checking the checkbox
any other way to do it is also fix my problem
This is my code
layout = [[sg.Text('Choose Options'))],
[sg.Checkbox('Save Posts',key="save-ed")],
[sg.Submit('Next')) ,sg.Cancel("Cancel"))] ]
window = sg.Window('my bot', layout, icon="logo.ico")
event, values = window.read()
window.close()
while True:
event, values = window.read()
if event == sg.WIN_CLOSED or event == "Cancel":
break
elif values['save-ed'] == True:
save_input = ['usersave']
elif values['save-ed'] == False:
save_input = ['#usersave']
and this is the code which i want to comment or uncomment with checkbox
try:
save_input = webdriver.find_element_by_xpath('/html/body/div[4]/div[2]/div/article/div[3]/section[1]/span[4]/div/div/button/div')
save_input.click()
sleep(randint(4,5))
except NoSuchElementException:
pass
Following code show how to stop a thread to update time by a checkbox.
from datetime import datetime
from time import sleep
import threading
import PySimpleGUI as sg
def clock(window):
now = None
while timer:
new = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
if new != now:
now = new
if flag:
window.write_event_value('CLOCK', now)
sleep(0.1)
sg.theme("DarkBlue3")
sg.set_options(font=("Courier New", 16))
layout = [
[sg.Text("", size=(0, 1), key='TIME')],
[sg.Checkbox("Time ON", default=True, enable_events=True, key='TIME ON')],
]
window = sg.Window('Title', layout, finalize=True)
timer, flag = True, True
threading.Thread(target=clock, args=(window,), daemon=True).start()
while True:
event, values = window.read()
if event == sg.WINDOW_CLOSED:
timer = False
break
elif event == 'TIME ON':
flag = values[event]
elif event == 'CLOCK':
window['TIME'].update(values[event])
window.close()
according to previous comment and answer by #jason-yang
i got the point and changed the code like this and fixed my problem
layout = [[sg.Text('Choose Options'))],
[sg.Checkbox('Save Posts',key="save-ed")],
[sg.Submit('Next')) ,sg.Cancel("Cancel"))] ]
window = sg.Window('my bot', layout, icon="logo.ico")
event, values = window.read()
window.close()
while True:
event, values = window.read()
if event == sg.WIN_CLOSED or event == "Cancel":
break
if event == "save posts":
if values['save-ed'] == True:
save_input = values['usersave']
elif values['save-ed'] == False:
save_input = values['#usersave']
the rest of the code seems to be correct and i leave it unchanged
try:
save_input = webdriver.find_element_by_xpath('/html/body/div[4]/div[2]/div/article/div[3]/section[1]/span[4]/div/div/button/div')
save_input.click()
sleep(randint(4,5))
except NoSuchElementException:
pass

Categories