'PySimpleGUI: How does one bind elements in a secondary window?
I have a main window with an element, key = -PATIENT-. When I exit the element a function runs to capitalise the entry and to update the element. All good. I also have a secondary window with an element,key = -NAME-. I want to be able to bind the secondary window element so that when I exit it, it will also run a similar function to capitalise the entry and update the element. This is where I have a problem. When a name is entered in the -PATIENT- element, on FocusOut the name is capitalised and checked against a list of names. If the names is not in the list a popup asks if it should be put into the secondary window element. If affirmative this is done. However, if from the dropdown menu (Edit) a new name should be added to the -NAME- element of the secondary window, then if the name is in lower case, the function to change its first letters to uppercase should run. I cannot get this binding to work for the secondary window. I am attaching a simple sample program (code) to illustrate the problem. Please help.
#CashBook.py
import PySimpleGUI as sg
import tkinter as tk
from tkinter import ttk
from tkcalendar import Calendar, DateEntry
import sqlite3
import datetime as dt
import time
from prettytable import PrettyTable
import subprocess, sys
from tkinter.filedialog import askopenfilename
sg.ChangeLookAndFeel('GreenTan')#LightGrey
menu_def = [['File', ['Open', 'Save', 'Exit' ]],
['Edit', ['Add a Patient','Add a Supplier']],
['Reports',['List of patients', 'List of suppliers','Income.....',['by category','by procedure','by patient'],'Expenses by category.....',['by category','by type','by supplier'],],],
['Help', 'About...'],]
layout1=[
[sg.T('Patient name:'),sg.In(size=(15,1),key='-PATIENT-')],
[sg.T('')],
[sg.T('')],
]
tabgrp=[[sg.TabGroup([[sg.Tab('Receipts',layout1,key='-RECEIPTS-'),#,title_color='Green',border_width=10,background_color='White',tooltip='Enter receipts',element_justification='centre'),
]], tab_location='topleft',
title_color='Red', tab_background_color='Purple',selected_title_color='Green',
selected_background_color='Gray', border_width=5)]]
layout3=[
[sg.T('Closing balance: '),sg.In(size=10,key='_CLOSBAL_'),sg.Push(),sg.Button('Close',button_color='red')]]
layout=[
[sg.Menu(menu_def, )],
[sg.Push(),sg.T('FootSmart Cash Book',font=('Verdana',24,'bold'),text_color='turquoise'),sg.Push()],
[sg.Push(),sg.T('Enter transaction details in one of the TABS below',font=('Verdana',18,'bold'),text_color ='turquoise'),sg.Push()],
[sg.T('')],
[sg.T('')],
[sg.T('')],
]
layout += tabgrp + layout3
window =sg.Window('Cash Book', layout, finalize=True)
""" Try the binding here. It does not work"""
#window.find_element['-NAME-'].bind('<FocusOut>','FOCUS OUT')
def capitalise_new_patient_names():
name=values(add_patient_window(['-NAME-']))
newname=name.title()
msg=''
print(newname)
def add_patient_window():
"""
Function to create secondary window
"""
add_patient_layout=[
[sg.Push(),sg.T('Add a patient',text_color='blue',font=40),sg.Push()],
[sg.T('')],
[sg.T('Patient name'),sg.Push(),sg.In(newname,size=20, key='-NAME-')],
]
add_patient_window=sg.Window('Add a new patient', add_patient_layout, modal=True,finalize=True)#Secondary window
while True: # Event loop for secondary window
event,values=add_patient_window.read() # Read secondary window
if event in (None,'Quit'):
break
elif event==window('-NAME-FOCUS OUT'):
capitalise_new_patient_names()
"""Try binding here. Also does not work"""
#window.find_element['-NAME-'].bind('<FocusOut>','FOCUS OUT')
add_patient_window.close()
#'++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++'
window['-PATIENT-'].bind('<FocusOut>','FOCUS OUT')
def capitalise_patient_names():
name=values['-PATIENT-']
Newname=name.title()
msg=''
print(Newname)
window['-PATIENT-'].update(Newname)
while True:
event, values = window.read()
print(event, values)
if event in (sg.WIN_CLOSED, 'Cancel','Close'):
break
elif event=='Add Patient':
add_patient_window()
elif event=='Add a Patient':
newname=""
add_patient_window()
elif event == '-PATIENT-FOCUS OUT':
capitalise_patient_names()
pat_name=values['-PATIENT-']
if not pat_name in ['Nicky Betts','Frank Aldridge','']:
print('This is a new patient ' + pat_name)
reply=sg.PopupOKCancel('Warning!', 'This is a new patient. Add patient?')
if reply=='OK':
newname=values['-PATIENT-'].title()
add_patient_window()
elif reply=='Cancel':
continue
window.close()
Solution 1:[1]
Didn't I already reply this issue about three days ago ?
Three issues found here
- Find element by
window[key]for call functionwindow.find_element(key), notwindow.find_element[key] - Don't use the same name for a function and a variable, like
def add_patient_window():
...
add_patient_window=sg.Window('Add a new patient', add_patient_layout, modal=True,finalize=True)#Secondary window
- Element with key '-NAME-' not defined in
window, so should be binded in windowadd_patient_window, not in windowwindow.
replace
...
window =sg.Window('Cash Book', layout, finalize=True)
window.find_element['-NAME-'].bind('<FocusOut>','FOCUS OUT')
...
def add_patient_window():
...
add_patient_window=sg.Window('Add a new patient', add_patient_layout, modal=True,finalize=True)
...
by
...
window =sg.Window('Cash Book', layout, finalize=True)
...
def add_patient_window():
...
patient_window=sg.Window('Add a new patient', add_patient_layout, modal=True,finalize=True)
patient_window.find_element('-NAME-').bind('<FocusOut>','FOCUS OUT')
# or patient_window['-NAME-'].bind('<FocusOut>','FOCUS OUT')
...
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Jason Yang |
