PySimpleGUI:如何在选项卡环境中绑定元素?

PySimpleGUI: How does one bind an element in a tab environment?

我有一个现金簿程序,它使用 TABS 将收据条目与费用条目分开。在 'Receipts' 和 'Expenses' 选项卡中都有一个用于输入货币值的 Input 元素。我想绑定元素,以便在失去焦点时将输入的数字转换为具有 2 个小数位的格式。 (参见:event=='-RECAMNT-FOCUS OUT':)。问题是,当我 运行 代码时,会出现一个错误,指出在调用 read() 或创建 window 时 finalize=True 之前,您无法对元素执行操作。 绑定在只有 main window(没有制表符)的程序中完美运行。谁能告诉我如何解决这个问题?我无法在 window 创建有 3 个布局的地方添加 'finalize=True'。 window =sg.Window('Cash Book',layout).Layout(tabgrp).layout(layout3)

我正在发布提取的代码以显示出现问题的位置。

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

sg.ChangeLookAndFeel('GreenTan')#LightGrey

menu_def = [['File', ['Open', 'Save', 'Exit'  ]],      
           ['Edit', ['Add a Patient','Add a Supplier']],
           ['Reports',['Fuel uplifts by registration','Fuel uplift by Town']],     
           ['Help', 'About...'], ] 

conn=sqlite3.connect(r'/home/bushbug/Databases/FSCashBook')
cur=conn.cursor()
query=cur.execute("SELECT DISTINCT(pName)from Patients Order by pName ASC")
patient_data=[]

for row in cur.fetchall():
    patient_data.append(row[0])
    cur.close()

conn=sqlite3.connect(r'/home/bushbug/Databases/FSCashBook')
cur=conn.cursor()
query=cur.execute("SELECT DISTINCT(sName)from Suppliers Order by sName ASC")
supp_data=[]

for row in cur.fetchall():
    supp_data.append(row[0])
    cur.close()

conn= sqlite3.connect(r'/home/bushbug/Databases/FSCashBook')
cur=conn.cursor()
query=cur.execute("SELECT IncCat from Analyse where Indicator = 'I' ")
I_Analyse_data=[]

for row in cur.fetchall():
    I_Analyse_data.append(row[0])
    #return data
    cur.close()

conn= sqlite3.connect(r'/home/bushbug/Databases/FSCashBook')
cur=conn.cursor()
query=cur.execute("SELECT IncCat from Analyse where Indicator = 'E' ")
E_Analyse_data=[]

for row in cur.fetchall():
    E_Analyse_data.append(row[0])
    #return data
    cur.close()

conn= sqlite3.connect(r'/home/bushbug/Databases/FSCashBook')
cur=conn.cursor()
query=("SELECT fBal from FSCashBook ORDER by Id DESC LIMIT 1")
result=cur.execute(query)

for row in result:
    Balance=row[0]

conn= sqlite3.connect(r'/home/bushbug/Databases/FSCashBook')
cur=conn.cursor()
query=("SELECT tDate from FSCashBook WHERE tInd = 'I' ORDER by Id DESC LIMIT 1 ")
result=cur.execute(query)

for row in result:
    LastDate=row[0]
    
layout1=[
[sg.T('Last transaction date',key='-RECTRANSDT-'),sg.In(LastDate,key='-IN4-', size=(10,1)),sg.T('Patient name:'),sg.Combo(patient_data,size=(15,1),key='-PATIENT-'),sg.Push(),sg.T('Amount'),sg.In(size=15,key='-RECAMNT-')],
[sg.T('')],
[sg.T('Document No:         '),sg.In(size=8,key='-RECDOC-'),sg.T(''),sg.T('Procedure'),sg.In(size=20,key='-PROC-'),sg.Push(),sg.T('Analysis:'),sg.Combo(I_Analyse_data,size=20,key='-RECANALYSE-')],
[sg.T('')],
[sg.CalendarButton('Choose receipt date',button_color='blue', target='-IN4-', format='%Y-%m-%d'),sg.Push(),sg.Button('Next Receipt',button_color='purple'),sg.Button('SaveRec',button_color='green')]]

layout2=[
[sg.T('Last transaction date'),sg.In(key='-IN5-', size=(10,1)),sg.T('Supplier name:'),sg.Combo(supp_data,size=20,key='-SUPPLIER-'),sg.Push(),sg.T('Amount'),sg.In(size=15,key='-EXPAMNT-')],
[sg.T('')],
[sg.T('Document No:         '),sg.In(size=8,key='-EXPDOC-'),sg.T(''),sg.T('Transaction details'),sg.In(size=20,key='-TRANSDET-'),sg.Push(),sg.T('Analysis:'),sg.Combo(E_Analyse_data,size=20,key='-EXPANALYSE-')],
[sg.T('')],
[sg.CalendarButton('Choose expense date',button_color='blue',  target='-IN5-', format='%Y-%m-%d'),sg.Push(),sg.Button('Next Expense',button_color='purple'),sg.Button('SaveExp',button_color='green')]]

tabgrp=[[sg.TabGroup([[sg.Tab('Receipts',layout1,key='-RECEIPTS-'),#,title_color='Green',border_width=10,background_color='White',tooltip='Enter receipts',element_justification='centre'),
sg.Tab('Expenses',layout2,key='-EXPENSES-')]], tab_location='topleft',
                       title_color='Red', tab_background_color='Purple',selected_title_color='Green',
                       selected_background_color='Gray', border_width=5), sg.Button('Close')]] 
layout3=[
[sg.T('Closing balance: '), sg.In(size=10,key='_CLOSBAL_')]]

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('')],
[sg.T('Opening balance: '), sg.In(Balance,size=10,key='_OPBAL_')]
]

window =sg.Window('Cash Book',layout).Layout(tabgrp).layout(layout3)

window['-RECAMNT-'].bind('<FocusOut>','FOCUS OUT')   

while True:
    event, values = window.read()
    print(event, values)
    if event in (sg.WIN_CLOSED, 'Cancel','Close'):
        break

    elif event=='-RECAMNT-FOCUS OUT':
        try:
            frecamnt = (values['-RECAMNT-'])
            frecamnt = "{: .2f}".format(float(frecamnt))
            window.find_element('-RECAMNT-').update(frecamnt)
            print(frecamnt)
            #continue
window.close()

Many of the Window methods require you to either call Window.read or Window.Finalize (or set finalize=True in your Window call) before you call the method. This is because these 2 calls are what actually creates the window using the underlying GUI Framework. Prior to one of those calls, the methods are likely to crash as they will not yet have their underlying widgets created.

我的建议

window =sg.Window('Cash Book',layout).Layout(tabgrp).layout(layout3)

window['-RECAMNT-'].bind('<FocusOut>','FOCUS OUT')  

应替换为

layout += tabgrp + layout3
window = sg.Window('Cash Book', layout, finalize=True)
window['-RECAMNT-'].bind('<FocusOut>','FOCUS OUT')