i can't close other windows - python

so i'm trying to make a question asker program that is connected to an access database and i'm having a problem i have a main window and i can't close other windows that i open after this is the code
import PySimpleGUI as sg
import pypyodbc
import random
sg.theme('darkgrey3')
conn = pypyodbc.connect(r'Driver={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=C:\Users\FUAD\Documents\Database9.accdb;')
main_menu = [
[sg.Text('PROJECT 1',pad=(70,40))],
[sg.Button('Add question',size=(10,3),key=('add_question'))],
[sg.Button('ask question',size=(10,3),key = ('-AskQuestion-'))],
[sg.Button('see all the questions',size=(10,3),key='-SeeAllTheQuestions-')]
]
window = sg.Window('project',main_menu)
while True:
cursor = conn.cursor()
cursor.execute('select * from Questions')
questionslist = cursor.fetchall()
sg.theme('darkblue')
def see_all_the_questions(delete, set):
layout = [
[sg.Text('What you want to do?', key='-text-'), sg.Push(), sg.Button('X', key='-Cancel*SeeQuestions-')],
[sg.Button('delete', key='-delete-'), sg.Button('set the question', key='-set-'),
sg.Button('Cancel', key='-cancel-', visible=False)],
[sg.Listbox(questionslist, s=(50, 25), key='-listbox-', enable_events=True)]
]
window = sg.Window('Question list', layout)
while True:
event, values = window.read()
if event == sg.WIN_CLOSED:
break
if event == '-delete-':
delete, set = True, False
window['-cancel-'].update(visible=True)
if event == '-cancel-':
delete, set = False, False
window['-cancel-'].update(visible=False)
if event == '-set-':
delete, set = False, True
window['-cancel-'].update(visible=True)
if event == '-listbox-' and delete == True:
cursor.execute(f'DELETE FROM Questions WHERE ID in ({values[event][0][0]})')
cursor.commit()
if event == '-listbox-' and set == True:
print('setted')
**def add_question(question):
sg.theme('darkbrown')
layout = [
[sg.Text('please enter your question'), sg.Push(), sg.Button('X', key='-Exit-')],
[sg.Input(key='-input-'), sg.Button('-Enter-')],
[sg.Text('Your question successfully added to questions!', key='sccful', visible=False)]
]
window = sg.Window('question adder', layout)
while True:
event, values = window.read()
if event == sg.WIN_CLOSED:
break
if event == '-Enter-' and values['-input-']!='':
print(questionslist)
print(questionslist[-1:][0])
question = (questionslist[-1:][0][0]+1,values['-input-'])
cursor.execute('''
INSERT INTO Questions VALUES(?,?)''',question)
cursor.commit()
break**
event,values = window.read()
if event == sg.WIN_CLOSED:
break
if event == '-SeeAllTheQuestions-':
see_all_the_questions(False,False)
if event == 'add_question':
add_question('')
in bold part of the code i'm trying to get information from user and when the user hits the enter i want to close that window but it just isn't what can i do
i tried to close the window

Related

pysimplegui Is there posible to add value to input and print it in windows

I would like to get value+2 in window after i input my number. i tried to to it that way but i dont understand how one variable is dic and str and diffrent time. Thats what i tried using pyspysimplegui example.
import PySimpleGUI as sg
layout = [
[sg.Text('x+2=:'), sg.Text(size=(15,1), key='-OUTPUT-')],
[sg.Input(key='-IN-')],
[sg.Button('Show'), sg.Button('Exit')]]
window = sg.Window('Pattern 2B', layout)
while True: # Event Loop
event, values = window.read()
if event == sg.WIN_CLOSED or event == 'Exit':
break
if event == 'Show':
print(type(event), values)
values += '2'
window['-OUTPUT-'].update(values['-IN-'])
window.close()
You got an event Show generated when you click on button Show, then window.read() in your while True event loop will return a 2-tuple, (event, values).
event is the event when window.read(), 'Show' here.
values is a dictionary with key:value of some elements, {'-IN-': ''} here.
The value of an Input element is in str, not int or number.
Refer Return Values
Revised code as
import PySimpleGUI as sg
layout = [
[sg.Text('x'), sg.Push(), sg.Input('', key='x')],
[sg.Text('x+2:'), sg.Push(), sg.Input('', disabled=True, key='x+2')],
[sg.Button('Show'), sg.Button('Exit')]]
window = sg.Window('Pattern 2B', layout)
while True: # Event Loop
event, values = window.read()
if event == sg.WIN_CLOSED or event == 'Exit':
break
elif event == 'Show':
x_string = values['x']
try:
x = int(x_string)
y = str(x + 2)
except ValueError:
y = "Wrong number !!!"
window['x+2'].update(value=y)
window.close()

Dynamically Updating an Element in a Multiple Window Setup

I have a quick question about updating fields dynamically in a multiple window setup such as the example above. I want it so that when the user selects autofill, values[SAVEINVENTORYPATH] is printed to the 'testinputtext' field in the settings window however when I use window.update, it searches for the keys in the main window rather than the settings window. How can I direct PySimpleGUI towards the settings window?
EDIT: Thank you for your help, I have edited the code and the autofill function works however currently, Autofill appears to freeze the window but I want people to be able to select Autofill and then hit Save and then the Settings window refreshes however I'm not sure where to currently place the while True loop. Thank you again for your assistance with this.
def create_settings_window(settings):
sg.theme('LightGrey6')
settings = load_settings(SETTINGS_FILE, DEFAULT_SETTINGS )
def TextLabel(text): return sg.Text(text+':', justification='r', size=(20,1))
layout = [ [sg.Text('Set Up Connection', font='Any 15')],
[TextLabel('Inventory List'), sg.Input(key='SAVEINVENTORYPATH'), sg.FileBrowse(key='INVENTORYLIST')],
[sg.Text(text='', key = 'testinputtext')],
[sg.Button('Save'), sg.Button('Autofill'), sg.Button('Exit')] ]
window = sg.Window('Settings', layout, keep_on_top=True, finalize=True,element_padding = (3,3.5))
test = window['testinputtext']
event, values = window.read()
if event == 'Autofill':
test.update(value = 'hi')
if event == 'Save':
save_settings(SETTINGS_FILE, settings, values)
sg.popup('Settings saved')
else:
print(event, values)
for key in SETTINGS_KEYS_TO_ELEMENT_KEYS:
try:
window[SETTINGS_KEYS_TO_ELEMENT_KEYS[key]].update(value=settings[key])
except Exception as e:
print(f'Problem updating PySimpleGUI window from settings. Key = {key}')
return window
def main():
window, settings = None, load_settings(SETTINGS_FILE, DEFAULT_SETTINGS )
while True: # Event Loop
#LAYOUT
if window is None:
settings = load_settings(SETTINGS_FILE, DEFAULT_SETTINGS )
sg.theme('LightGrey6')
layout = [[sg.Multiline(size=(180,10),key='Output',pad=(0,20))],
[sg.Button(button_text = 'Settings',key='Settings'),sg.Button(button_text = 'Load Output',key='LOAD_OUTPUT'),sg.Exit()]]
window = sg.Window('Settings Dynamic Update Test', layout, element_justification='center', size= (600,300))
event, values = window.read()
if event == sg.WIN_CLOSED or event == 'Exit':
break
window.close()
if event == 'Settings':
create_settings_window(settings)
else:
print(event, values)
window.close()
main()
It' better to handle each window in it's own event loop, mix windows together may get things mush difficult or complex.
Following example show the way to go.
import PySimpleGUI as sg
def popup():
sg.theme('DarkBlue4')
layout = [
[sg.Text("You name"), sg.Input("", key='Name')],
[sg.Text("", size=0, key='Test')],
[sg.Button('Save'), sg.Button('Auto Fill'), sg.Button('Cancel')],
]
window = sg.Window('Settings', layout, modal=True)
while True:
event, values = window.read()
if event in (sg.WIN_CLOSED, 'Cancel'):
flag = False
break
elif event == 'Save':
settings['Name'] = values['Name']
flag = True
break
elif event == 'Auto Fill':
window['Test'].update(values['Name'])
window.close()
return flag
def main_window():
sg.theme('DarkBlue3')
name = settings['Name']
value = name if name else 'None'
layout = [
[sg.Text("User Name:"), sg.Text(value, key='Name')],
[sg.Button('Settings'), sg.Button('Exit')],
]
return sg.Window('Main', layout)
settings = {'Name':None}
window = main_window()
while True:
event, values = window.read()
if event in (sg.WIN_CLOSED, 'Exit'):
break
elif event == 'Settings':
flag = popup()
if flag:
window.close()
window = main_window()
""" or just update element
name = settings['Name']
value = name if name else 'None'
window['Name'].update(value)
"""
window.close()

with python schedule tray can't open and can't perform any action

i was make a program in python for desktop application. and create a login form for employee and after login i was create a schedule call a api for check employee is login or not and open a pop up message for Acknowledgement for login employee.
my problem is when schedule start so i can so stop the code
import PySimpleGUI as sg
import requests
from psgtray import SystemTray
import json
import schedule
from schedule import *
import gtts
import threading
import time
def make_sch(user_id: object, emp_name: object):
schedule.every(4).seconds.do(func_msg, user_id, emp_name)
while True:
schedule.run_pending()
time.sleep(4)
def func_msg(user_id: object, emp_name: object):
response_msg = '{ "msg": "Data Found","status": 1,"Data": "hello team","id": 2}'
response_msg_json: object = json.loads(response_msg)
print(response_msg_json)
if str(response_msg_json['status']) == '1' and str(response_msg_json['id']) != '':
sg.theme('DarkTeal9') # Add a touch of color
layout = [[sg.Text(response_msg_json['Data'])],
[sg.Text('Enter your Acknowledge'), sg.Multiline(size=(50, 5), key='textbox')],
[sg.Button('Enter'), sg.Button('Cancel')],
[sg.Text(size=(40, 1), key='ACK_OUTPUT')]]
# Create the Window
window = sg.Window('Team Alert', layout)
# Event Loop to process "events" and get the "values" of the inputs
while True:
event, values = window.read()
if event == sg.WIN_CLOSED or event == 'Cancel': # if user closes window or clicks cancel
break
elif event == 'Enter' and values['textbox'] == '':
window['ACK_OUTPUT'].update('Please enter your Acknowledgement', text_color='red')
else:
window['ACK_OUTPUT'].update('', text_color='red')
response_update = '{"msg": "Data Found","status": 1}'
response_update_json: object = json.loads(response_update)
sg.Popup('Thanks For Your Acknowledgement!!')
window.close()
window.close()
def main():
menu = ['',
['Show Window', 'Hide Window', '---', '!Disabled Item', 'Exit']]
tooltip = 'Team Alert'
sg.theme('DarkTeal9')
layout = [[sg.Text("* Enter Your Id")],
[sg.Input(key='emp_id')],
[sg.Text(size=(40, 1))],
[sg.Text("* Enter Your Password")],
[sg.Input(key='emp_pass')],
[sg.Text(size=(40, 1), key='-OUTPUT-')],
[sg.Button('Login')]]
window = sg.Window('Team Alert', layout, finalize=True, enable_close_attempted_event=True)
tray = SystemTray(menu, single_click_events=True, window=window, tooltip=tooltip)
tray.show_message('Team Alert', 'Team Alert Started!')
sg.cprint(sg.get_versions())
while True:
event, values = window.read()
if values['emp_id'] and values['emp_pass']:
response = '{ "msg": "Sucessfully login", "status": 1}'
login_data_json: object = json.loads(response)
if str(login_data_json['status']) == '1':
window.hide()
tray.show_icon()
window['-OUTPUT-'].update(login_data_json['msg'], text_color='yellow')
emp_id = values['emp_id']
emp_name = 'emp'
make_sch(emp_id, emp_name)
else:
window['-OUTPUT-'].update(login_data_json['msg'], text_color='red')
if event == 'Login':
sg.Popup(login_data_json['msg'])
else:
window['-OUTPUT-'].update('** Username and Password is required', text_color='red')
if event == tray.key:
sg.cprint(f'Team Alert Event = ', values[event], c='white on red')
event = values[event]
if event in (sg.WIN_CLOSED, 'Exit'):
sg.Popup("You are Logout!!")
break
sg.cprint(event, values)
tray.show_message(title=event, message=values)
if event in ('Show Window', sg.EVENT_SYSTEM_TRAY_ICON_DOUBLE_CLICKED):
window.un_hide()
window.bring_to_front()
elif event in ('Hide Window', sg.WIN_CLOSE_ATTEMPTED_EVENT):
window.hide()
tray.show_icon()
elif event == 'Hide Icon':
tray.hide_icon()
elif event == 'Show Icon':
tray.show_icon()
elif event == 'Change Tooltip':
tray.set_tooltip(values['-IN-'])
tray.close()
window.close()
print('this is event', event)
if __name__ == '__main__':
main()
Following code for different case, but for your reference about how to work with multithread.
from time import sleep
import threading
import math
import PySimpleGUI as sg
def capture_data(window):
global duration, running
theta = 0
while running:
x = [(i+theta)/180*math.pi for i in range(w)]
y = [sum([math.sin(i*j)/i/math.pi for i in range(1, 8, 2)])*h+h//2 for j in x]
x = [i for i in range(w)]
window.write_event_value('Plot', [(i, j) for i, j in zip(x, y)])
theta = (theta+1) % 360
sleep(duration)
font = ("Courier New", 11)
sg.theme("DarkBlue3")
sg.set_options(font=font)
w, h = size = (360, 240)
layout = [
[sg.Graph(size, (0, 0), size, background_color='green', key='Graph')],
[sg.Push(), sg.Button('Exit')]
]
window = sg.Window('Matplotlib', layout, finalize=True)
graph = window['Graph']
theta, duration, running, curve = 0, 0.01, True, None
threading.Thread(target=capture_data, args=(window, ), daemon=True).start()
while True:
event, values = window.read()
if event in (sg.WINDOW_CLOSED, 'Exit'):
running = False
sleep(0.1)
break
elif event == 'Plot':
points = values['Plot']
if curve:
graph.delete_figure(curve)
curve = graph.draw_lines(points, color='white', width=1)
window.close()

python system tray error not working with schedule

when i run this code and do login after. i am doing start system schedule in python when i start schedule so s system tray icon will be created on system tray and system tray i have given event for system exit form this code but problem is i can't exit after click on this when i start the schedule
please someone help me solve this problem
username: emp
password: emp
import PySimpleGUI as sg
import requests
from psgtray import SystemTray
import json
import schedule
from schedule import *
import gtts
import threading
import time
def make_sch(user_id: object, emp_name: object):
schedule.every(4).seconds.do(func_msg, user_id, emp_name)
while True:
schedule.run_pending()
time.sleep(4)
def func_msg(user_id: object, emp_name: object):
response_msg = '{ "msg": "Data Found","status": 1,"Data": "hello team","id": 2}'
response_msg_json: object = json.loads(response_msg)
print(response_msg_json)
if str(response_msg_json['status']) == '1' and str(response_msg_json['id']) != '':
sg.theme('DarkTeal9') # Add a touch of color
layout = [[sg.Text(response_msg_json['Data'])],
[sg.Text('Enter your Acknowledge'), sg.Multiline(size=(50, 5), key='textbox')],
[sg.Button('Enter'), sg.Button('Cancel')],
[sg.Text(size=(40, 1), key='ACK_OUTPUT')]]
# Create the Window
window = sg.Window('Team Alert', layout)
# Event Loop to process "events" and get the "values" of the inputs
while True:
event, values = window.read()
if event == sg.WIN_CLOSED or event == 'Cancel': # if user closes window or clicks cancel
break
elif event == 'Enter' and values['textbox'] == '':
window['ACK_OUTPUT'].update('Please enter your Acknowledgement', text_color='red')
else:
window['ACK_OUTPUT'].update('', text_color='red')
response_update = '{"msg": "Data Found","status": 1}'
response_update_json: object = json.loads(response_update)
sg.Popup('Thanks For Your Acknowledgement!!')
window.close()
window.close()
def main():
menu = ['',
['Show Window', 'Hide Window', '---', '!Disabled Item', 'Exit']]
tooltip = 'Team Alert'
sg.theme('DarkTeal9')
layout = [[sg.Text("* Enter Your Id")],
[sg.Input(key='emp_id')],
[sg.Text(size=(40, 1))],
[sg.Text("* Enter Your Password")],
[sg.Input(key='emp_pass')],
[sg.Text(size=(40, 1), key='-OUTPUT-')],
[sg.Button('Login')]]
window = sg.Window('Team Alert', layout, finalize=True, enable_close_attempted_event=True)
tray = SystemTray(menu, single_click_events=True, window=window, tooltip=tooltip)
tray.show_message('Team Alert', 'Team Alert Started!')
sg.cprint(sg.get_versions())
while True:
event, values = window.read()
if values['emp_id'] and values['emp_pass']:
response = '{ "msg": "Sucessfully login", "status": 1}'
login_data_json: object = json.loads(response)
if str(login_data_json['status']) == '1':
window.hide()
tray.show_icon()
window['-OUTPUT-'].update(login_data_json['msg'], text_color='yellow')
emp_id = values['emp_id']
emp_name = 'emp'
make_sch(emp_id, emp_name)
else:
window['-OUTPUT-'].update(login_data_json['msg'], text_color='red')
if event == 'Login':
sg.Popup(login_data_json['msg'])
else:
window['-OUTPUT-'].update('** Username and Password is required', text_color='red')
if event == tray.key:
sg.cprint(f'Team Alert Event = ', values[event], c='white on red')
event = values[event]
if event in (sg.WIN_CLOSED, 'Exit'):
sg.Popup("You are Logout!!")
break
sg.cprint(event, values)
tray.show_message(title=event, message=values)
if event in ('Show Window', sg.EVENT_SYSTEM_TRAY_ICON_DOUBLE_CLICKED):
window.un_hide()
window.bring_to_front()
elif event in ('Hide Window', sg.WIN_CLOSE_ATTEMPTED_EVENT):
window.hide()
tray.show_icon()
elif event == 'Hide Icon':
tray.hide_icon()
elif event == 'Show Icon':
tray.show_icon()
elif event == 'Change Tooltip':
tray.set_tooltip(values['-IN-'])
tray.close()
window.close()
print('this is event', event)
if __name__ == '__main__':
main()
Your code have lot of problems, like
Execution blocked when call schedule
Update GUI in schedule
Wrong event for SystemTray
something else.
Different code by using multithread to call schedule, update GUI in main loop and event generated in multithread by call window.write_event_value.
import time
import threading
import schedule
from psgtray import SystemTray
import PySimpleGUI as sg
def loop(window):
schedule.every(4).seconds.do(update_gui, window)
while running:
schedule.run_pending()
time.sleep(1)
def update_gui(window):
global user
window.write_event_value("Func_MSG", user)
time.sleep(1)
window.write_event_value("Func_MSG_Close", None)
def popup_win(username):
sg.theme('DarkBlue4')
return sg.Window('Team Alert', [[sg.Text(f'Hello, {username.title()}')]], finalize=True)
font = ("Courier New", 11)
sg.theme("DarkBlue3")
sg.set_options(font=font)
users = {'James':'1234', 'Mary':'5678'}
layout = [
[sg.Text('Username'), sg.Input(key='Username')],
[sg.Text('Password'), sg.Input(key='Password')],
[sg.Text('', expand_x=True, key='Message')],
[sg.Push(), sg.Button("Login"), sg.Button('Exit')],
]
window = sg.Window("test", layout, finalize=True)
tooltip = 'Team Alert'
menu = ['', ['Show Window', 'Hide Window', 'Exit']]
tray = SystemTray(menu, single_click_events=True, window=window, tooltip=tooltip)
running, user = False, None
while True:
event, values = window.read()
if event in (sg.WINDOW_CLOSED, 'Exit'):
break
elif event == '-TRAY-':
case = values[event]
if case == 'Exit':
break
elif case in ('Show Window', sg.EVENT_SYSTEM_TRAY_ICON_DOUBLE_CLICKED):
window.un_hide()
window.bring_to_front()
elif case in ('Hide Window', sg.WIN_CLOSE_ATTEMPTED_EVENT):
window.hide()
tray.show_icon()
if event == 'Login':
username, password = values['Username'], values['Password']
if username in users and users[username]==password:
window.hide()
window['Message'].update('Login successful !')
user = username
if not running:
running = True
threading.Thread(target=loop, args=(window, ), daemon=True).start()
else:
window['Message'].update("Wrong username and/or password !")
elif event == "Func_MSG":
username = values[event]
win = popup_win(username)
elif event == "Func_MSG_Close":
if win:
win.close()
running = False
tray.close()
window.close()
Following code show how to use option timeout to call function periodically without using schedule.
from psgtray import SystemTray
import PySimpleGUI as sg
def popup_win(username):
sg.theme('DarkBlue4')
layout = [
[sg.Text(f'Hello, {username.title()}')],
[sg.Button('OK')],
]
sg.Window('Team Alert', layout).read(close=True)
font = ("Courier New", 11)
sg.theme("DarkBlue3")
sg.set_options(font=font)
users = {'James':'1234', 'Mary':'5678'}
layout = [
[sg.Text('Username'), sg.Input(key='Username')],
[sg.Text('Password'), sg.Input(key='Password')],
[sg.Text('', expand_x=True, key='Message')],
[sg.Push(), sg.Button("Login"), sg.Button('Exit')],
]
window = sg.Window("test", layout, finalize=True)
tooltip = 'Team Alert'
menu = ['', ['Show Window', 'Hide Window', 'Exit']]
tray = SystemTray(menu, single_click_events=True, window=window, tooltip=tooltip)
running, user = False, None
while True:
event, values = window.read(timeout=4000)
if event in (sg.WINDOW_CLOSED, 'Exit'):
break
elif event == '-TRAY-':
case = values[event]
if case == 'Exit':
break
elif case in ('Show Window', sg.EVENT_SYSTEM_TRAY_ICON_DOUBLE_CLICKED):
window.un_hide()
window.bring_to_front()
elif case in ('Hide Window', sg.WIN_CLOSE_ATTEMPTED_EVENT):
window.hide()
tray.show_icon()
if event == 'Login':
username, password = values['Username'], values['Password']
if username in users and users[username]==password:
window['Message'].update('Login successful !')
user = username
running = True
else:
window['Message'].update("Wrong username and/or password !")
elif event == sg.TIMEOUT_EVENT and running and user:
popup_win(user)
tray.close()
window.close()

PySimpleGUIQt - pressing key or button as action

import PySimpleGUIQt as sg
layout = [
[sg.Button('Button1')],
[sg.Button('Exit')],
]
window = sg.Window('Mechanical Turk tool', self._layout)
while True:
event, values = window.read()
if event == sg.WIN_CLOSED or event == 'Exit':
break
elif event == 'Button1': # how to make it possible to also press "a" on your keyboard to run that event?
print("You pressed button 1")
How do I modify above code, so I can press "button1" on GUI but also "a" on keyboard to start specified event?
Set option return_keyboard_events=True in sg.Window, then simulate a click on button1 in your event loop.
import PySimpleGUIQt as sg
layout = [
[sg.Button('Button1')],
[sg.Button('Exit')],
]
window = sg.Window('Mechanical Turk tool', layout, finalize=True, return_keyboard_events=True)
while True:
event, values = window.read()
if event in (sg.WIN_CLOSED, 'Exit'):
break
elif event == 'Button1':
print("You pressed button 1")
elif event == 'a':
window['Button1'].click()
window.close()

Categories

Resources