I'm trying to write a phonebook application using Tkinter. It's not very advanced, and it's mentioned in this tutorial:
http://openbookproject.net//py4fun/gui/tkPhone.html
The full source of the tutorial's version being here:
http://openbookproject.net//py4fun/gui/tkPhone.py

However, I'm trying to write a version myself, yet I keep getting the following error:

File "phonebook_test.py", line 96, in ? win = MakeWindow()
File "phonebook_test.py", line 55, in MakeWindow
Load_but = Button(f2,text="Load", command=load())
File "phonebook_test.py", line 13, in load
name, phone = phonelist[whichSelected()]
File "phonebook_test.py", line 10, in whichSelected
return int(Contacts_lbox.curselection())
NameError: global name 'Contacts_lbox' is not defined

My code is here:

from Tkinter import *

phonelist = [['Mary Mag', '01467393'], ['Bob hilder', '9370703'], ['Fire & Res', '999']]

def whichSelected () :
    
    #print "At %s of %d" % (Contacts_lbox.curselection(), len(phonelist))
    return int(Contacts_lbox.curselection())

def load():
    name, phone = phonelist[whichSelected()]
    name_string.set(name)
    number_string.set(phone)

def MakeWindow():

    global Contacts_lbox, number_string, name_string

    win = Tk()

    ###frame 1###

    f1 = Frame(win)

    name = StringVar()
    number = StringVar()

    name_string = StringVar()
    name_box = Entry(f1,textvariable=name_string)

    number_string = StringVar()
    number_box = Entry(f1,textvariable=number_string)

    name_label = Label(f1,text="Name:")
    number_label = Label(f1,text="Number:")

    #Pack/Grid statements
    f1.pack()
    name_label.grid(row=0,column=0)                    
    name_box.grid(row=0,column =1)
    number_label.grid(row =1, column =0)
    number_box.grid(row =1,column=1)

    ###frame 2###

    f2 = Frame(win)

    Add_but = Button(f2,text="Add")
    Update_but = Button(f2,text="Update")
    Delete_but = Button(f2,text="Delete")
    Load_but = Button(f2,text="Load", command=load())

    #Pack/Grid statements
    f2.pack()
    Add_but.grid(row =0, column = 0)
    Update_but.grid(row =0, column = 1)
    Delete_but.grid(row =0, column = 2)
    Load_but.grid(row =0, column = 3)

    ###frame 3###

    #Declarations

    f3 = Frame(win)
    Contacts_lbox = Listbox(f3,height=5)
    Scroll = Scrollbar (f3,orient=VERTICAL)

    #Pack statements
    f3.pack()
    Contacts_lbox.pack(side = RIGHT, fill =BOTH)
    Scroll.pack(side=LEFT,fill = Y)

    #Configure Statements
    Scroll.configure(command=Contacts_lbox.yview)
    Contacts_lbox.configure(yscrollcommand=Scroll.set)

    return win 
    
def setSelect () :
    
    phonelist.sort()
    Contacts_lbox.delete(0,END)
    for name,phone in phonelist :
        Contacts_lbox.insert(END, name)

win = MakeWindow()
setSelect ()
win.mainloop()

The purpose of the load button is to display in the text boxes the information about the selected listbox entry.
setSelect sorts and then displays the contents of the listbox.
The contents of the listbox are stored within phonelist.
WhichSelected() returns the index of the selected item within the listbox (Contacts_lbox).

I've tried placing my global declaration in all sorts of places, and i've tried googling, but I just can't see what the solution to my problem is. Any help would be greatly appreciated!

Also, what does:
print "At %s of %d" % (Contacts_lbox.curselection(), len(phonelist))
(It's commented out - near the top) actually do? Because I can't work that out either.

I'd be grateful for any help.

Recommended Answers

All 2 Replies

I write a lot of python code and almost never use global declarations :). In fact you must use a global declaration when you want to assign a value to a global variable in a function, like your line

Contacts_lbox = Listbox(f3,height=5)
[/codeh
however it works only if your variable is already a global name. When compiling your code, python makes a collection of your global names. Global variables refer to names in this collection.
A solution to your problem is to add lines like
[code=python]
Contacts_lbox = None
number_string = None
name_string = None

somewhere at global level (for example at the top of your file). These variables become global names.

Another (and better solution) is probably to avoid global variables and to make an object with properties Contact_lbox, etc. This would imply more changes to your code...

Thanks, that fixed the problem, but I hit another :P
I think I will recode it, either making it object orientated, or simply passing those variables through all my functions.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.