0

Iam new in Python, and my set goal is trying to create an application for myself to list and manipulate some data; in my case some coins. I am self teaching code, but there are many thing I do not understand yet.

Iam organizing the code as best as I could, but I have reached some of my limits.

My code is showing a Tk window which is containing the data that you enter in a second window using Toplevel. When you use the ADD button it shows the window, but if you happen to close it and open it again, it shows an error. Iam sure it is because my instance of the window is destroyed but I would love to have your input about how I should solve this issue. What would you suggest ?

Thanks for your time !

from tkinter import *  # tkinter package import
from tkinter import ttk


window_size = '480x600+0+0'

############################ Window 1 configuration ############################
window = Tk()
window.title('Coin Collector')  # title of the window
window.geometry(window_size)  #taille de la fenetre
window.config(background='white')

#searchbar
search_bar_txt = Label(window, text='Search :')
search_bar_txt.place(height=40,width=70,x=1,y=1)
search_bar_entry = Entry(window)
search_bar_entry.place(height=40,width=410,x=71,y=1)

# tree view setup
tree=ttk.Treeview(window)
tree['columns']=('one','two','three')
tree.column('#0', width=29, minwidth=80)
tree.column('one', width=150, minwidth=80)
tree.column('two', width=150, minwidth=80)
tree.column('three', width=147, minwidth=80)

tree.heading('#0',text='#ID')
tree.heading('one', text='COIN')
tree.heading('two', text='YEAR')
tree.heading('three', text='PRICE')

tree.place(height= 510,x=0, y=50)



def show_window2():
    window_2.deiconify()

###### BUTTONS ########
Button_add = Button(window, text='ADD', command=show_window2)
Button_add.place(height=40, width=120, x=0, y=560)

Button_remove = Button(window, text='REMOVE')
Button_remove.place(height=40, width=120, x=120, y=560)

Button_edit = Button(window, text='EDIT')
Button_edit.place(height=40, width=120, x=240, y=560)

Button_exit = Button(window, text='EXIT', command=exit)
Button_exit.place(height=40, width=120, x=360, y=560)


############################ Window 2 configuration ############################
window_2 = Toplevel()
window_2.title('Edit coin')
window_2.geometry('300x500+480+0')
window_2.config(background='white')
window_2.iconify()
window_2.protocol('WM_DELETE_WINDOW', window_2.destroy);#Changes close button

#coin type
coin_type_txt = Label(window_2, text='Coin Name :')
coin_type_txt.place(x=0, y=0)
coin_type_value = Entry(window_2)
coin_type_value.place(height=30, width=165, x=130, y=0)

#coin year
coin_year_txt = Label(window_2, text='Coin year :')
coin_year_txt.place(x=0, y=35)
coin_year_value = Entry(window_2)
coin_year_value.place(height=30, width=165, x=130, y=35)

#coin price
coin_price_txt = Label(window_2, text='Coin price :')
coin_price_txt.place(x=0, y=70)
coin_price_value = Entry(window_2,width=10)
coin_price_value.place(height=30, width=165, x=130, y=70)

def save_coin(): #create function to execute when clicked
    tree.insert('','end',text='',values=(coin_type_value.get(),coin_year_value.get(),coin_price_value.get()))

#save coin
coin_save_button = Button(window_2, text='save', command=save_coin)
coin_save_button.place(height=40, width=300, x=0, y=460)


######FUNCTIONS######

def exit():
    window.destroy()

window.mainloop()

2 Answers2

0

The way I do this is to move the creation of the toplevel and its widgets into a function. Then you can check for whether the window exists or not when displaying it. If it doesn't exist because the user destroyed it, you can recreate it.

For example, your show_window would look something like this:

def show_window2():
    if not window_2.winfo_exists():
        create_window2()
    window_2.deiconify()
Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
0

Hey thanks for the answer. It is working !

I now have created a function Addcoin_window(), and I call it from a button ADD which is located just some lines after.

Is there any way to organise my code, so that all my functions could be located at the end of my program ? Its just that I find it "messy" to have the function Addcoin_window() located on what I considered my main window organisation. Is that the Python way ?

Once again thanks for your help.

from tkinter import *  # tkinter package import
from tkinter import ttk


window_size = '480x600+0+0'

############################ Window 1 configuration ############################
window = Tk()
window.title('Coin Collector')  # title of the window
window.geometry(window_size)  #taille de la fenetre
window.config(background='white')

#searchbar
search_bar_txt = Label(window, text='Search :')
search_bar_txt.place(height=40,width=70,x=1,y=1)
search_bar_entry = Entry(window)
search_bar_entry.place(height=40,width=410,x=71,y=1)

# tree view setup
tree=ttk.Treeview(window)
tree['columns']=('one','two','three')
tree.column('#0', width=29, minwidth=80)
tree.column('one', width=150, minwidth=80)
tree.column('two', width=150, minwidth=80)
tree.column('three', width=147, minwidth=80)

tree.heading('#0',text='#ID')
tree.heading('one', text='COIN')
tree.heading('two', text='YEAR')
tree.heading('three', text='PRICE')

tree.place(height= 510,x=0, y=50)

def Addcoin_window():
    window_2 = Toplevel()
    window_2.title('Edit coin')
    window_2.geometry('300x500+480+0')
    window_2.config(background='white')
    #window_2.iconify()
    window_2.protocol('WM_DELETE_WINDOW', window_2.destroy);#Changes close button

    #coin type
    coin_type_txt = Label(window_2, text='Coin Name :')
    coin_type_txt.place(x=0, y=0)
    coin_type_value = Entry(window_2)
    coin_type_value.place(height=30, width=165, x=130, y=0)

    #coin year
    coin_year_txt = Label(window_2, text='Coin year :')
    coin_year_txt.place(x=0, y=35)
    coin_year_value = Entry(window_2)
    coin_year_value.place(height=30, width=165, x=130, y=35)

    #coin price
    coin_price_txt = Label(window_2, text='Coin price :')
    coin_price_txt.place(x=0, y=70)
    coin_price_value = Entry(window_2,width=10)
    coin_price_value.place(height=30, width=165, x=130, y=70)

    def save_coin(): #create function to execute when clicked
        tree.insert('','end',text='',values=(coin_type_value.get(),coin_year_value.get(),coin_price_value.get()))

    #save coin
    coin_save_button = Button(window_2, text='SAVE', command=save_coin)
    coin_save_button.place(height=40, width=300, x=0, y=460)

###### BUTTONS ########
Button_add = Button(window, text='ADD', command=Addcoin_window)
Button_add.place(height=40, width=120, x=0, y=560)

Button_remove = Button(window, text='REMOVE')
Button_remove.place(height=40, width=120, x=120, y=560)

Button_edit = Button(window, text='EDIT')
Button_edit.place(height=40, width=120, x=240, y=560)

Button_exit = Button(window, text='EXIT', command=exit)
Button_exit.place(height=40, width=120, x=360, y=560)



######FUNCTIONS######

def exit():
    window.destroy()

window.mainloop()