UnboundLocalError: local variable 'name_chk' referenced before assignment - python

I have created a Bank Management System using Tkinter and MySQL in Python.
def deposit_acc_chk():
mycursor.execute("SELECT name FROM bank_master WHERE acno = '"+deposit_entry1.get()+"'")
for x in mycursor:
name_chk = ''.join(map(str, x))
deposit_chk_entry.delete(0, "end")
deposit_chk_entry.insert(0, name_chk)
deposit_chk_entry["state"] = "disabled"
This code snippet displays the name of the Account holder depositing the money. It was working fine initially but then it showed an error.
Traceback (most recent call last):
File "C:\Users\HP\AppData\Local\Programs\Python\Python38-32\lib\tkinter\__init__.py", line 1883, in __call__
return self.func(*args)
File "C:\Users\HP\Desktop\BMS - GUI v1.1.2.py", line 196, in deposit_acc_chk
deposit_chk_entry.insert(0, name_chk)
UnboundLocalError: local variable 'name_chk' referenced before assignment
I tried to declare the variable name_chk, explicitly, as global and even tried referring some already answered questions of this type but it was not much helpful.
My error is still not resolved! Please help me.
P.S. - I am new here so please excuse me if I fail to correctly describe my question!

It is because there is no record returned by the SQL statement, so name_chk is not created.
You should check whether there is record returned before updating deposit_chk_entry:
def deposit_acc_chk():
mycursor.execute('SELECT name FROM bank_master WHERE acno = %s', (deposit_entry1.get(),))
rec = mycursor.fetchone()
if rec:
deposit_chk_entry['state'] = 'normal'
deposit_chk_entry.delete(0, 'end')
deposit_chk_entry.insert(0, rec[0])
deposit_chk_entry['state'] = 'disabled'
Or better show something to user if no record found:
def deposit_acc_chk():
mycursor.execute('SELECT name FROM bank_master WHERE acno = %s', (deposit_entry1.get(),))
rec = mycursor.fetchone()
name_chk = rec[0] if rec else '*** No record found ***'
deposit_chk_entry['state'] = 'normal'
deposit_chk_entry.delete(0, 'end')
deposit_chk_entry.insert(0, name_chk)
deposit_chk_entry['state'] = 'disabled'

You should
declare the name_chk variable before the line (this way, initialization occurs too)
deposit_chk_entry.insert(0, name_chk) such as
import tkinter as tk
root = tk.Tk()
name_chk = tk.StringVar()
or
call deposit_acc_chk() function between end of this function and
the line deposit_chk_entry.insert(0, name_chk) in order to incur the definition of the variable
name_chk within that function

Related

Delete item from dictionary and Listbox

I have a program that puts the contents of a dictionary in a Tkinter Listbox, but I'm having trouble deleting it from the Listbox and the dictionary.
from tkinter import *
import ast
f = open("orders.txt", "r")
contents = f.read()
f.close()
things = ast.literal_eval(contents)
secondthing = [things, "test"]
root = Tk()
f = Frame(root).pack()
l = Listbox(root)
b = Button(root, text = "delete selection", command = lambda: delete(l))
b.pack()
l.pack()
for i, j in things.items():
oneitem = i + " " + j
l.insert(END, oneitem)
def delete(listbox):
global things
# Delete from Listbox
selection = l.curselection()
l.delete(selection[0])
# Delete from list that provided it
evaluater = l.get(selection[0])
value = eval(evaluater)
ind = things.index(value)
del(things[ind])
print(things)
root.mainloop()
When I try to delete something it gives me:
Exception in Tkinter callback
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/tkinter/__init__.py", line 1883, in __call__
return self.func(*args)
File "/Users/mimmo/black_market/aaa.py", line 12, in <lambda>
b = Button(root, text = "delete selection", command = lambda: delete(l))
File "/Users/mimmo/black_market/aaa.py", line 28, in delete
value = eval(evaluater)
File "<string>", line 1
ohhh ohhhhh
^
SyntaxError: unexpected EOF while parsing
Can someone help me because I can delete it from the Listbox, I just have an error when deleting it from the dictionary.
The contents of orders.txt:
{"ayyy" : "ayyyyyy", "ohhh" : "ohhhhh"}
First of all, I would recommend using json or pickle to store contents of the dictionary - it's the most common practice. I don't really understand what do you want to do so I wrote a function which deletes an element from listbox and things by it's index.
An error you are getting is caused by eval function which tries to intepret your listbox item as python code. Of course, it's getting syntax error.
# Deletes element from listbox and thigs by it's index
def delete(listbox, index: int):
global things
item = listbox.get(index)
key = item.split()[0]
del things[key]
listbox.delete(index)

Attribute Error in python. Object has no attribute

This code is part of a bigger program that uses the google Sheets API to get data from a cloud database (not really relevant, but a bit of context never hurt!)
I have this black of code in one python file named 'oop.py'
class SetupClassroom:
def __init__(self, arraynumber='undefined', tkroot='undefined'):
self.arraynumber = arraynumber
self.tkroot = tkroot
def setarraynumber(self, number):
from GUI_Stage_3 import showclassroom
self.arraynumber = number
print ('set array number:', number)
showclassroom()
def settkroot(self, tkrootinput):
self.tkroot = tkrootinput
self.tkroot has been assigned by another part of the code. This bit works, as I have already tested that it is being assigned, however, when I call 'self.tkroot' in another another file like this
def showclassroom():
from oop import SetupClassroom
username = current_user.username
classnumber = getnumberofuserclassrooms(username)
if SetupClassroom.arraynumber > classnumber:
errorwindow('you are not enrolled in that many classrooms!')
else:
classtoget = SetupClassroom.arraynumber
print('classtoget:', classtoget)
root = SetupClassroom.tkroot
name_label = Label(root, text=classtoget)
getclassroom(username, classtoget)
SetupClassroom = SetupClassroom
I get this error
Exception in Tkinter callback
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/tkinter/__init__.py", line 1705, in __call__
return self.func(*args)
File "/Users/jonathansalmon/PycharmProjects/Coursework_GUI/GUI_Stage2_better.py", line 176, in <lambda>
l0 = ttk.Button(teacher_root, text=button0text, command=lambda: (SetupClassroom.setarraynumber(SetupClassroom, number=button0text), SetupClassroom.settkroot(SetupClassroom, 'teacher_root')))
File "/Users/jonathansalmon/PycharmProjects/Coursework_GUI/oop.py", line 99, in setarraynumber
showclassroom()
File "/Users/jonathansalmon/PycharmProjects/Coursework_GUI/GUI_Stage_3.py", line 29, in showclassroom
root = SetupClassroom.tkroot
AttributeError: type object 'SetupClassroom' has no attribute 'tkroot'
I tried setting it up in the python console and it worked, so I have no idea what the problem is.
If anyone could help, it would be very much appreciated
Thanks!
John
You should create an instance of class, it will create the attribute in __init__, self.tkroot is the attribute of instance not class:
setupClassroom = SetupClassroom()
print(setupClassroom.tkroot)
Hope that will help you.

Python Tkinter: Resetting a previously defined variable with Entry

I'm trying to make it so that when a user enters their name, password, etc, it stores it globally so that the program is able to connect with that name. I've defined the variables at top like this:
global server
server = ""
global nick
nick = ""
global altnick
altnick = ""
global password
password = ""
global channel
channel = ""
Then, when the Tkinter program comes in, the user can use the Entries to enter all the proper values:
networktop = Toplevel(master=root)
networktop.title("Network List")
networktop.geometry("300x220")
Label(networktop, text="Nickname:").pack()
nickbox = Entry(networktop)
nickbox.grid(column="50", row="50")
nickbox.pack()
nick = nickbox.get()
Label(networktop, text="Alternate nick:").pack()
altbox = Entry(networktop)
altbox.grid(column="50", row="50")
altbox.pack()
altnick = altbox.get()
Label(networktop, text="Password:").pack()
pwbox = Entry(networktop, show="*")
pwbox.grid(column="50", row="50")
pwbox.pack()
password = pwbox.get()
Label(networktop, text="Channel to join:").pack()
chanbox = Entry(networktop)
chanbox.grid(column="50", row="50")
chanbox.pack()
channel = chanbox.get()
listvar = StringVar(networktop)
listvar.set("Choose a network...") # default value
listnetwork = OptionMenu(networktop, listvar, "irc.freenode.net")
listnetwork.config(width="50")
listnetwork.grid(column="50", row="50")
listnetwork.pack()
server = listvar.get()
networkconnect = Button(networktop, text="Connect", command=connect)
networkcancel = Button(networktop, text="Cancel", command=networktop.destroy)
networkcancel.pack(side=LEFT)
networkconnect.pack(side=RIGHT)
What I'm trying to achieve here is that when something is entered in (e.g. "NickName") it replaces nick = "" at top with nick = "NickName", so that when "Connect" is pressed it would connect to the server with "NickName". But I get the following error:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python27\lib\lib-tk\Tkinter.py", line 1470, in __call__
return self.func(*args)
File "C:\Users\dell\Desktop\irchat.py", line 29, in connect
irc.connect((server, 6667))
File "C:\Python27\lib\socket.py", line 224, in meth
return getattr(self._sock,name)(*args)
error: [Errno 10049] The requested address is not valid in its context
I feel like I'm being a total noob here and the solution is probably easy as pie. xD
It appears you are getting the value of the entry widget before the user has an opportunity to enter any text. You're creating the widget and then immediately getting the value. Because of this, server is the empty string and thus the socket code is failing.
You don't want to get the value until the user has click the Connect button.

Python and tkinter: NameError: global name 'roomChange' is not defined

I'm receiving the following error:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python33\lib\tkinter\__init__.py", line 1475, in __call__
return self.func(*args)
File "D:\COMPUTER SCIENCE\Seating Plan\SeatingPlan TEST.py", line 205, in displayText
if roomChange.get().strip() == "":
NameError: global name 'roomChange' is not defined
When attempting to run the following code:
from tkinter import *
import tkinter.messagebox
def displayText():
""" Display the Entry text value. """
global roomChange
if roomChange.get().strip() == "":
tkinter.messagebox.showerror("Invalid Value", "Please enter a valid classroom name.")
else:
tkinter.messagebox.showinfo("Temporary Window", "Text value = " + roomChange.get().strip())
def roomChanger():
chrm = Tk()
chrm.title("Change Room")
chrm.wm_iconbitmap('./Includes/icon.ico')
chrm["padx"] = 40
chrm["pady"] = 20
# Create a text frame to hold the text Label and the Entry widget
textFrame = Frame(chrm)
#Create a Label in textFrame
roomChangeLabel = Label(textFrame)
roomChangeLabel["text"] = "Enter name of classroom: "
roomChangeLabel.pack(side=LEFT)
# Create an Entry Widget in textFrame
roomChange = Entry(textFrame)
roomChange["width"] = 50
roomChange.pack(side=LEFT)
textFrame.pack()
roomChangeButton = Button(chrm, text="Submit", command=displayText)
roomChangeButton.pack()
chrm.mainloop()
testButton = Button(window, text='Change Room', command=roomChanger)
testButton.place(x = 825, y = 360)
Can anyone suggest a solution to my problem?
Thanks
In roomChanger() you assign to roomChange:
roomChange = Entry(textFrame)
so you need to mark that name as a global inside that function too. Add a global roomChange statement in that function.
displayText() on the other hand, never tries to assign to roomChange and the global statement in that function can safely be removed.
I had the same problem.
Here was my solution:
from tkinter import *
from tkinter import messagebox
Some sort of namespace glitch. That second line shouldn't be necessary. Technically from a syntax perspective import * implies import messagebox too because it's part of it all.
Use those two lines, take away import tkinter.messagebox

Class Variable Retrieval in Python

This is a GUI I’ve been writing for a script I already have working. What I’m struggling with here is retrieving the information in the textboxes.
Under the definition generate I am able to pop a name off of listx but I am unable to grab the local variable entry from any of the instances of the new_title_box class.
from Tkinter import *
import ttk
boxvar=""
folder=""
listx=[]
count = 1
myrow = 1
class new_title_box:
def __init__(self,name):
global myrow, count, listx
self.entry = StringVar()
self.name = name
self.name = ttk.Entry(mainframe,width=45,textvariable=self.entry)
self.name.grid(column=1,row=myrow+1,sticky=(N,W))
listx.append(name)
print(listx) ## For debugging to insure that it is working correctly, if it gives output it, this part works
myrow = myrow + 1
count=count+1
def make_new(*args):
new_title_box('box'+str(count))
def generate(*args):
global listx, boxvar
while len(listx) > 0:
boxvar=listx.pop(0)
print(boxvar) ## For debugging to insure that it is working correctly, if it gives output it, this part works
folder = boxvar.entry.get() ## Not working here
print(folder) ## For debugging to insure that it is working correctly, if it gives output it, this part works
root = Tk()
root.title("File Maker")
mainframe = ttk.Frame(root, padding = "50 50 50 50")
mainframe.grid(column = 0,row = 0,sticky = (N, W, E, S))
mainframe.columnconfigure(0,weight=1)
mainframe.columnconfigure(0,weight=1)
add_entry = ttk.Button(mainframe,width=20, text = "add entry", command=make_new)
add_entry.grid(column=2,row=2,sticky=(N,W))
add_entry = ttk.Button(mainframe,width=20, text = "make files", command=generate)
add_entry.grid(column=2,row=3,sticky=(N,W))
root.mainloop()
Here's the traceback I'm getting:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python33\lib\tkinter_init_.py", line 1442, in call
return self.func(*args)
File "C:\python\SampAqTkinter.py", line 28, in generate
folder = boxvar.entry ## Not working here
AttributeError: 'str' object has no attribute 'entry'
There are two things that need to be changed to fix the problem you describe:
In the new_title_box.__init__() method change: listx.append(name) to listx.append(self.name)
In the generate() function, change: folder = boxvar.entry.get() to folder = boxvar.get().
You are appending a string to listx, use self.name instead of the local string name

Categories

Resources