'How does one create a secondary window using PySimpleGUI?

I have been trying to create a second window for my program written with PySimpleGUI but just cannot get it to work. I have tried different approaches but none seem to work. I am providing the code for a two window program obtained from You Tube (a simple calculator) which obviously works well and then the code for my program using the structure of the You Tube program. First, if I indent the code for the secondary window in my program the same as the Calculator it throws out an error "inconsistent use of tabs and spaces in indentation". If I unindent the code the program runs but then exits with the error:" NameError: name 'add_car_layout' is not defined". I have spent hours trying to solve these problems without success. Can anyone throw some light on the matter please? Thank you in advance.

#Calculator

import PySimpleGUI as sg
import math

sg.change_look_and_feel('DarkAmber')

layout=[
[sg.T('Enter radius in centimeters'),sg.In(key='_RADIUS_',do_not_clear=True,size=(5,1))],
[sg.In(size=(20,1), justification='right',key='_OUT_CALCULATION_'),
sg.T('centrmetres cubed ')],
[sg.Button('Calculate Volume'),sg.Button('Calculate Area'), sg.Button('Quit')]
]

window=sg.Window('Calculate sphere volume',layout,size=(580,100))  #Main window

def calculate_area_window(): #Function for creating seconday window

    calculate_area_layout=[
    [sg.T('Enter radius in centimeters'),sg.In(key='_RADIUS_',do_not_clear=True,size=(5,1))],
    [sg.In(size=(20,1), justification='right',key='_OUT_AREA_CALCULATION_'),
    sg.T('centrmetres squared ')],
    [sg.Button('Calculate Area'), sg.Button('Quit')]
    ]

    calculate_area_window=sg.Window('Calculate circle area',calculate_area_layout,modal=True) #Secondary window

    while True:#Event loop for secondary window
        event, values = calculate_area_window.read()
        if event in (None,'Quit'):
            break
        elif event=='Calculate Area':
            radius=float(values['_RADIUS_'])
            area="{: .2f}".format(math.pi*(radius**2))
            print(area)
        calculate_area_window['_OUT_AREA_CALCULATION_'].update(area)

    calculate_area_window.close() #Close secondary window


while True:#Event loop for Main window
    event, values = window.read()
    if event in (None,'Quit'):
        break
    elif event=='Calculate Volume':
        radius=float(values['_RADIUS_'])
        volume="{: .2f}".format((4/3)*math.pi*(radius**3))
        print(volume)
        window['_OUT_CALCULATION_'].update(volume)
    elif event=='Calculate Area':
        calculate_area_window()

window.close() #Close Main window

My Program

import tkinter as tk
from tkinter import ttk
from tkcalendar import Calendar, DateEntry
import sqlite3
from datetime import date
import time

import PySimpleGUI as sg

sg.ChangeLookAndFeel('GreenTan')  #GreenTan

TodayDt=date.today()

menu_def = [['File', ['Open', 'Save', 'Exit'  ]],      
           ['Edit', ['Add a Vehicle']],     
           ['Help', 'About...'], ]      

 
conn= sqlite3.connect(r'/home/bushbug/Databases/VehInfo')
cur=conn.cursor()

car_data=cur.execute("SELECT vReg from Vehicles")

car_data=[]

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

    print(car_data)

town_=cur.execute("SELECT tName from Towns")

town_data=[]

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

cur.close()
conn.close()

conn= sqlite3.connect(r'/home/bushbug/Databases/VehInfo')
cur=conn.cursor()
print('Connected')

layout=[
[sg.Menu(menu_def, )], 
[sg.T("")],
[sg.T("")],
[sg.Push(),sg.T("Enter Vehicle Logbook Data",  font=(50),text_color='blue'),sg.Push()],
[sg.T("")],
[sg.T("")],
[sg.T("Today's date is:            "),sg.In(TodayDt, size=(10, 10), key='_TODAYCAL_'),sg.Push()],       
[sg.T("Choose a car:               "), sg.Combo(car_data,size=(15,1),key='_CAR_',enable_events=True,tooltip='Please select a car from the dropdown box')],
[sg.T("Last transaction date:"),sg.T(" "), sg.In(size=10,key='-LastDate-'),sg.Push(),sg.T("Select new transaction date:"),sg.CalendarButton('Calendar',  target='-IN4-', key='_DATE_',format='%Y-%m-%d'),sg.In(key='-IN4-', size=(10,1))],
[sg.T("Odometer reading:         "),sg.In(size=(12,1),key='_ODO_',enable_events=True,),sg.T("    "),sg.T("   New Odometer reading:   "),sg.In(size=(12,1),enable_events=True,key='_NEWODO_'),sg.T("Distance travelled:    "),sg.In(key='_DIST_',enable_events=True,size=(11,1))],
[sg.T("Refuelling town:(Select) "),sg.Combo(town_data,size=(15,1),key='_TOWN_',default_value='Swakopmund')],
[sg.T("Fuel quantity (in litres):   "),sg.In(key="_FUELQUANT_",size=(10,1),enable_events=True),sg.Push(),sg.T("Fuel amount N$:"),sg.In(key="_FUELAMNT_", size=(10,1),enable_events=True)],
[sg.T("Oil quantity (in millilitres: "),sg.In(key="_OILQUANT_",size=(10,1)),sg.Push(),sg.T("Oil amount N$:"),sg.In(key="_OILAMNT_",size=(10,1))],
[sg.T("Other items:                   "),sg.In(key="_OTHERITEMS_",size=(10,1)),sg.Push(),sg.T("Other amount N$:"),sg.In(key="_OTHERAMNT_",size=(10,1))],
[sg.Push(),sg.Button('Save',size=12,button_color='red',key='-Save-',disabled=True),sg.Button('Calculate Totals YTD',button_color='green',disabled=True,key='-CalcYTD-'),sg.Button('Next Record',size=12,disabled=True,button_color='blue',key='-Next-')],
[sg.T('_'*100)],
[sg.Push(),sg.T("Trip Economy",font=12,text_color="green"),sg.Push(),sg.Push(),sg.T("Economy (Progressive YTD)", font=6,text_color="green"),sg.Push()],
[sg.T("Economy in Kms/Ltr:"),sg.In(size=6,key='-KmsLtr-'),sg.T('Kms/Ltr'),sg.T("                                   The fuel economy to date, in Kms/Ltr is:"),sg.T(""),sg.In(size=6,key='Kms_Per_Ltr'),sg.T('Kms/Ltr')],
[sg.T("Economy in N$/Km: "),sg.In(size=6,key='-NamKms-'),sg.T('N$/Km'),sg.Text("                                 "),sg.T('The fuel cost to date, in N$/Km is:        '),sg.T(""),sg.In(size=6,key='N$_Per_Km'),sg.T('N$/Km ')],
[sg.T("Fuel price: "),sg.T("           "),sg.In(size=6,key='FuelPrice'),sg.T("N$"),sg.T("                                       "),sg.T("The average price of fuel to date is:"),sg.T("       "),sg.In(size=6,key="AvePrice"),sg.T('N$   ')]    
]

window = sg.Window('My Vehicle Logbook', layout, finalize=True) #Main window


def add_car_window():# Function to create secondary window

    add_car_layout=[
    [sg.Push(),sg.T('Add a vehicle'),sg.Push()],
    [sg.T('Vehicle make:'),sg.In(size=20,key='-MAKE-')]
    [sg.Button('Quit')]
    ]

add_car_window=sg.Window('Add a new vehicle',add_car_layout,modal=True)#Secondary window

while True:#Event loop for secondary window

    event,values=add_car_window.read()#Read secondary window
    if event in (None,'Quit'):
        break

add_car_window.close()#Close secondary window

#======================================================================================================
while True:#Event loop for Main window

    event, values = window.read()#Read Main window

    if event == sg.WIN_CLOSED or event == 'Exit':     # if user closes window or clicks cancel
        break

    elif event == 'Add a Vehicle':

        add_car_window()

window.close()#Close Main window


Solution 1:[1]

Second window as a popup window defined in function add_car_window should be like this.

def add_car_window():
    """
    Function to create secondary window
    """
    add_car_layout=[
        [sg.Push(),sg.T('Add a vehicle'),sg.Push()],
        [sg.T('Vehicle make:'),sg.In(size=20, key='-MAKE-')]
        [sg.Button('Quit')]
    ]

    add_car_window=sg.Window('Add a new vehicle', add_car_layout, modal=True)#Secondary window

    while True:                             # Event loop for secondary window

        event,values=add_car_window.read()  # Read secondary window
        if event in (None,'Quit'):
            break

    add_car_window.close()                  # Close secondary window

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