Main module calls the module which I have posted. I am trying to create a point of sale and this particular code renames the title of the program.
Here is my code:
from Globalvariables import *
from tkinter import *
#Mart Name
#user accounts
def settingsmain():
settingmenu = Toplevel()
settingmenu.iconbitmap('D:/Gatlabs logo.ico')
labelformartname = Label(settingmenu, text = "Enter name of your store")
entryformartname = Entry(settingmenu)
entryformartname.grid(row = 0, column = 0)
setmartname = Button(settingmenu, text = "setname", command = setname)
setmartname.grid(row= 0, column = 1)
settingmenu.mainloop()
def setname():
global Mname
Mname = entryformartname.get()
Although I have imported Tkinter and created an entry widget, I get error:
"NameError: name 'entryformartname' is not defined"
Where am I mistaken?
As the entryformartname has been defined in a different function and in the line -:
Mname = entryformartname.get()
you're tryna access it in a different function, it gives the error entryformartname not defined.
Now, as the entryformartname is a local variable of only the specific function where it's defined, so if you wanna use it in some other function or somewhere else generally, you'll have to make it a global var.
It's really simple to make it a global variable. Just use the keyword global like so in the function where it's defined -:
global entryformartname # The code is used to declare that entryformartname is a global variable.
This should make it global. But still until you've told the other function, that the entryformartname variable you wanna access is global and not local you have to import it into the other function which can be done like so -:
global entryformartname # The same code but this time used for importing the global var.
So adding these lines in both functions should solve your problem.
Hope it helps
And hope you're safe in the times of an ongoing pandemic.
You could use a global variable.like:
def settingsmain():
global entryformartname
settingmenu = Toplevel()
settingmenu.iconbitmap('D:/Gatlabs logo.ico')
labelformartname = Label(settingmenu, text="Enter name of your store")
entryformartname = Entry(settingmenu)
entryformartname.grid(row=0, column=0)
setmartname = Button(settingmenu, text="setname", command=setname)
setmartname.grid(row=0, column=1)
settingmenu.mainloop()
def setname():
global Mname,entryformartname
Mname = entryformartname.get()
Related
I have a combo box containing all of the countries and as the user picks a country, the country picked is stored in the variable country inside of a function. However, I will need to access the local variable (country) outside of the function. Can somebody help me find a way to access the local variable outside the function it is declared in.
import tkinter as tk
from tkinter import ttk
from tkinter.messagebox import showinfo
root = tk.Tk()
root.geometry('500x500')
countries = ('afghanistan',
'albania',
'algeria',
'andorra',
'angola',
'anguilla',)
countries_cb = ttk.Combobox(root)
countries_cb['values'] = countries
countries_cb['state'] = 'readonly'
countries_cb.pack(fill='y', padx=5, pady=5)
def countries_changed(event):
msg = f'You selected {countries_cb.get()}!'
showinfo(message=msg)
country=(countries_cb.get()) #the local variable i want to access outside of the function
print(country)
countries_cb.bind('<<ComboboxSelected>>', countries_changed)
root.mainloop()
If you want to just read the value of local variable in outside of the function, return it from the function. Like this
def countries_changed(event):
msg = f'You selected {countries_cb.get()}!'
showinfo(message=msg)
country=(countries_cb.get()) #the local variable i want to access outside of the function
print(country)
country_local = countries_changed(event, country)
Or if you want to modify it in outside the function, use global keyword.
country = ''
def countries_changed(event):
global country
msg = f'You selected {countries_cb.get()}!'
showinfo(message=msg)
country=(countries_cb.get()) #the local variable i want to access outside of the function
print(country)
print(country)
Since the variable country is local, you can't access it from outside the function.
The keyword global helps with this issue.
Try:
def countries_changed(event, country):
global country
msg = f'You selected {countries_cb.get()}!'
showinfo(message=msg)
country=(countries_cb.get()) #the local variable i want to access outside of the function
print(country)
I am trying to call a function from another Python file after a button is click. I have imported the file and used the FileName.fuctionName() to run the function. The problem is my exception keeps catching. I am guessing that the data from the function being called is not being grabbed.What I am trying to do is have a user fill out a Tkinter gui then click a button. Once the button is click the user will then be asked to scan their tag (rfid) and that data will then be sent to a firebase real time database which will store the user's inputted info along with the card_id and user_id that was created when the tag was scanned.
Im kinda at a loss because other than the exception catching I am not getting any other errors, any thoughts? I have posted the code below along with comments.
error : local variable 'user_id' referenced before assignment
from tkinter import *
#Second File
import Write
from tkcalendar import DateEntry
from firebase import firebase
data = {}
global user_id
# Firebase
firebase= firebase.FirebaseApplication("https://xxxxxxx.firebaseio.com/",None)
# button click
def sub ():
global user_id
#setting Variables from user input
name = entry_1.get()
last = entry_2.get()
number = phone.get()
try:
#Calling Function from other file
Write.scan()
if Write.scan():
#getting the New User Id
user_id= new_id
#User Info being sent to the Database
data = {
'Name #': name,
'Last': last,
'Number': number,
'Card #':user_id
}
results = firebase.post('xxxxxxxx/User',data)
except Exception as e:
print(e)
# setting main frame
root = Tk()
root.geometry('850x750')
root.title("Registration Form")
label_0 = Label(root, text="Registration form",width=20,font=("bold", 20))
label_0.place(x=280,y=10)
label_1 = Label(root, text="First Name",width=20,font=("bold", 10))
label_1.place(x=80,y=65)
entry_1 = Entry(root)
entry_1.place(x=240,y=65)
label_2 = Label(root, text="Last Name",width=20,font=("bold", 10))
label_2.place(x=68,y=95)
entry_2 = Entry(root)
entry_2.place(x=240,y=95)
phoneLabel = Label(root, text="Contact Number : ",width=20,font=("bold", 10))
phoneLabel.place(x=400,y=65)
phone = Entry(root)
phone.place(x=550,y=65)
Button(root, text='Submit',command = sub,width=20,bg='brown',fg='white').place(x=180,y=600)
root.mainloop()
Write.py file being Imported
import string
from random import*
import RPi.GPIO as GPIO
from mfrc522 import SimpleMFRC522
reader = SimpleMFRC522()
#Function being called
def scan():
try:
#Creating user hash
c = string.digits + string.ascii_letters
new_id = "".join(choice(c) for x in range(randint(25,25)))
print("Please Scan tag")
#Writing to tag
reader.write(new_id)
if reader.write(new_id):
print("Tag Scanned")
else:
print("Scan Tag First")
print("Scanning Complete")
finally:
GPIO.cleanup()
I see that the value new_id in one file isn't going to influence the value with the same name in the other file, for a similar reason as for the first problem. In both places it appears, new_id is a local variable that only exists in the enclosing function.
Another issue I see is that you're calling Write.scan() twice in a row. Do you mean to be calling it twice? I expect not.
Also, you're testing the return value of Write.scan(), but that function doesn't return a value. So I think that the code in the if block in the first file will never run.
Globals are a bad idea in general, as they're easy to get wrong and they tend to obscure what the code is really doing. "Never say never", but I'll say that I very rarely find the need for a global variable in Python. In your case, I think it would be much better to have Write.scan() return the value of the new user id instead of passing it back as a global. Since you're testing the value of Write.scan(), maybe this is what you were thinking of doing already. Here are the changes I'd make to address these three issues and hopefully get your code working the way you want...
...
def sub ():
...
try:
#Calling Function from other file
new_id = Write.scan()
if new_id:
#getting the New User Id
user_id= new_id
...
...
def scan():
try:
...
new_id = "".join(choice(c) for x in range(randint(25,25)))
...
return new_id
finally:
GPIO.cleanup()
It's impossible to tell what your problem is, because there is no place in your code that references user_id and hence the error message you cite can't come from the code you provide. However, I see a pretty common mistake that your code appears to be making that could very well account for why you expect user_id to be defined somewhere in your code and yet it is not...
In your first block of code, the global user_id is not being set by the sub function. Rather, when the sub function calls user_id=new_id, it is creating and setting a variable that is local to that function. When that function ends, the result of that call is lost and the global user_id is still undefined.
What you want is to define user_id as being global inside of the sub() function. Just add global user_id anywhere near the top of the function definition.
Here's an example of what I'm talking about:
global x
def sub():
x = 3
sub()
print(x)
result:
Traceback (most recent call last):
File "t", line 7, in <module>
print(x)
NameError: global name 'x' is not defined
whereas:
global x
def sub():
global x
x = 3
sub()
print(x)
result:
3
I've got some code that creates a context menu when the user selected a word in a tkinter text widget. The text widget automatically checks to see if the word is correct every time 'space' is pressed. if the selected word is incorrect, part of the context menu asks the user if they would like to correct the word. This should then get the selected word, loop through the text widget (using the search method) until it's found an instance of the word, then replace it with the correct word.
Here is my code (don't mind the 'WOOOO!', it just allows the user to use the context menu with out selecting a word)
from tkinter import *
root = Tk()
notepad = Text(root)
def replace_word():
global selected_word
global context_word
replace_start = notepad.search(selected_word, 1.0, END)
while replace_start:
replace_offset = '+%dc' % len(selected_word)
replace_end = replace_start + replace_offset
notepad.delete(replace_start, replace_end)
notepad.insert(replace_start, context_word)
replace_start = notepad.search(replace_start, 1.0, END)
def add_to_dictionary_context():
global selected_word
global context_word
global spell_dict
spell_dict.word_frequency.add(selected_word)
with open('dictionary_file_add.txt', 'a+') as f_context:
selected_word_to_add = selected_word + '\n'
f_context.write(selected_word_to_add)
def notepad_context_menu(event):
global spell_dict
context_menu = Menu(notepad_frame, tearoff = 0)
try:
selected_word = notepad.selection_get().strip('\n')
context_word = spell_dict.correction(selected_word)
if (selected_word not in spell_dict) and (selected_word != context_word): # Makes sure selected_word is incorrect
dictionary_context = Menu(context_menu, tearoff = 0)
context_menu.add_cascade(label = "Dictionary... ", menu = dictionary_context)
dictionary_context.add_command(label = context_word, command = replace_word)
dictionary_context.add_command(label = "Add to dictionary", command = add_to_dictionary_context)
context_menu.add_separator()
except:
print("WOOOO!")
context_menu.add_command(label = "Undo", command = undo)
context_menu.add_command(label = "Redo", command = redo)
context_menu.add_separator()
context_menu.add_command(label = "Cut", command = cut)
context_menu.add_command(label = "Copy", command = copy)
context_menu.add_command(label = "Paste", command = paste)
try:
context_menu.tk_popup(event.x_root, event.y_root)
finally:
context_menu.grab_release()
notepad.bind('<Button-3>', notepad_context_menu)
root.mainloop()
However, when I run this code, if I press the replace word button in the context menu it returns the error:
File "C:\Users\User\Documents\Python stuff\Other apps\Veteris\Scripts\Veteris_program.py", line 1058, in replace_word
replace_start = notepad.search(selected_word, 1.0, END)
NameError: name 'selected_word' is not defined
and if I press the 'Add to dictionary' button it returns:
File "C:\Users\User\Documents\Python stuff\Other apps\Veteris\Scripts\Veteris_program.py", line 1068, in replace_word
notepad.insert(replace_start, context_word)
NameError: name 'context_word' is not defined
Basically, my code isn't reading my global statements. My add_word_to_dictionary_context() and replace_word() functions only run after I've declared context_word and selected_word.
I've tried putting
selected_word = ''
context_word = ''
at the start, and no error is returned but nothing happens. I've also tried putting replace_word() and add_to_dictionary-context() after notepad_context_menu(), but it still spits the same errors.
I'm really stuck.
Thanks for the help :)
You will need to add the global statements to the functions where you assign (write, as it were) into the global functions, not into those which just read them.
Your code is writing them in the notepad_context_menu function:
selected_word = notepad.selection_get().strip('\n')
context_word = spell_dict.correction(selected_word)
and since you don't have declared them global in that function, they're just local variables which get "thrown away".
On the other hand, you don't need to declare spell_dict global in any of these functions, since you're not assigning into it.
That said, it'd be much better not to use global variables to begin with, e.g. by using anonymous lambda functions that capture those values and pass them in:
def replace_word(selected_word, context_word):
pass # ...
def add_to_dictionary_context(selected_word):
spell_dict.word_frequency.add(selected_word)
# ...
def notepad_context_menu(event):
# ...
selected_word = notepad.selection_get().strip("\n")
context_word = spell_dict.correction(selected_word)
# ...
dictionary_context.add_command(
label=context_word,
command=lambda: replace_word(selected_word, context_word),
)
dictionary_context.add_command(
label="Add to dictionary",
command=lambda: add_to_dictionary_context(selected_word),
)
I know this was answer already by AKX but as explained you should be posting a MRE. Though you have updated your question it is still not an MRE. You are missing the required import for spell checking and your notepad was never added to the screen.
Here is an example of what an MRE might look like including correction to make it work.
You needed to provide global for context_word and selected_word into your notepad_context_menu. They way functions look for variable is like this:
First it checks locally for the variable and if the variable is not defined locally it will then check the global namespace for the variable. So for functions that only work with the variable and do not define it we do not need the global defined in the function. However for functions that will be defining a variable IE var = something then we need to set the global in the function.
I also added global to your replace_word function as here I am resetting context_word and selected_word back to "" after replace is finished.
Note I removed all the parts that are not part of the testing for this issue. IE all the context_menu items unrelated to the spell check and the redundant replace_start in your function.
Lastly I made some PEP8 changes to your formatting.
Let me know if you have any questions:
import tkinter as tk
import spellchecker as sc
root = tk.Tk()
notepad = tk.Text(root)
notepad.pack()
spell_dict = sc.SpellChecker()
context_word = ''
selected_word = ''
def replace_word():
global context_word, context_word, selected_word
replace_start = notepad.search(selected_word, 1.0, "end")
replace_offset = '+%dc' % len(selected_word)
replace_end = replace_start + replace_offset
notepad.delete(replace_start, replace_end)
notepad.insert(replace_start, context_word)
context_word = '' # added to reset context and selected words.
selected_word = ''
def add_to_dictionary_context():
global selected_word
spell_dict.word_frequency.add(selected_word)
with open('dictionary_file_add.txt', 'a+') as f_context:
selected_word_to_add = selected_word + '\n'
f_context.write(selected_word_to_add)
def notepad_context_menu(event):
global spell_dict, selected_word, context_word
context_menu = tk.Menu(notepad, tearoff=0)
try:
selected_word = notepad.selection_get().strip('\n')
context_word = spell_dict.correction(selected_word)
if selected_word not in spell_dict and selected_word != context_word:
dictionary_context = tk.Menu(context_menu, tearoff=0)
context_menu.add_cascade(label="Dictionary... ", menu=dictionary_context)
dictionary_context.add_command(label=context_word, command=replace_word)
dictionary_context.add_command(label="Add to dictionary", command=add_to_dictionary_context)
context_menu.add_separator()
except:
print("WOOOO!")
try:
context_menu.tk_popup(event.x_root, event.y_root)
finally:
context_menu.grab_release()
notepad.bind('<Button-3>', notepad_context_menu)
root.mainloop()
I'm invoking one function using a button click. But it is giving me error: NameError: global name 'new' is not defined ,even though I have defined new as a new window.
My code for a new window:
def result():
root.withdraw()
new = Toplevel()
new.geometry("1105x605+300+300")
button3 = Button(new, text='Select a Query Image',command = matching_image)
button3.pack(padx = 1, pady = 1,anchor='ne')
button3.place( x = 570, y = 60)
The button will invoke matching_image function, and the code will be:
def matching_image():
path1 = tkFileDialog.askopenfilename(filetypes=[("Image File",'.jpg')])
im = Image.open(path1)
resized = im.resize((200, 200),Image.ANTIALIAS)
tkimage = ImageTk.PhotoImage(resized)
myvar1 = Label(new,image = tkimage)
myvar1.image = tkimage
myvar1.pack()
myvar1.place(x = 30, y = 100)
And this is giving the error. The error message is as follows:
%run "D:/6th sem/Major project/Code/frame.py"
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\HP\AppData\Local\Enthought\Canopy32\App\appdata\canopy-1.0.3.1262.win-x86\lib\lib-tk\Tkinter.py", line 1410, in __call__
return self.func(*args)
File "D:\6th sem\Major project\Code\frame.py", line 194, in matching_image
myvar1 = Label(new,image = tkimage)
NameError: global name 'new' is not defined
Any suggestions! So that I can solve this error.
Thanks in advance :)
You defined new in a function, so that variable only exists in that function's scope. Therefore, when you try to access it in another scope (here it is the global scope) you will get a NameError as it is not available at that level.
You can fix this by doing global new at the start of the function in which you define it.
This statement puts it in the global scope, meaning that it is defined at the module level. Therefore, you can access it anywhere in the program and you will not get that error.
Like this:
def result():
global new
new = Toplevel()
# Other stuff.
Though note that doing global declarations is considered bad practice. Much better to put your code in class form and assign applicable variables to self.
Your problem is condensed down to this:
def foo():
var = 1
def bar():
print var
foo()
bar()
The principle problem you have is that 'var' is a local, not a global.
This code example works:
def foo():
global var
var = 1
def bar():
print var
foo()
bar()
Because var is declared to be global instead.
I'm having some issues with the following code. This is the first time that I'm working with a GUI and it's been a while since I've worked with python as well. When I try to execute the solfield function with the button, it yields no output.
from Tkinter import *
import math
master = Tk()
n = float()
I = float()
def solfield():
pass
label_coils = Label(text='Number of Coils Per Meter', textvariable=n)
label_coils.grid()
coils = Entry(master)
coils.grid()
label_current = Label(text='Current in Amps', textvariable=I)
label_current.grid()
current = Entry(master)
current.grid()
calculate_button = Button(text='Calculate', command=solfield())
calculate_button.grid()
label_bfield = Label(text='B Field in +z Direction')
label_bfield.grid()
label_result = Label(text='solfield')
label_result.grid()
master.title('Coil Gun Simulation')
master.mainloop()
def solfield():
mu0 = math.pi*4e-7
solfield = mu0*n*I
print solfield
Any other tips would be appreciated as well, as there will eventually be much more coding for me to do.
This has been solved. If anyone is interested, here is the code after several fixes were made:
from Tkinter import *
import math
master = Tk()
label_coils = Label(text='Number of Coils Per Meter')
label_coils.grid()
coils = Entry(master)
coils.grid()
label_current = Label(text='Current in Amps')
label_current.grid()
current = Entry(master)
current.grid()
def solfield():
mu0 = math.pi*4e-7
n = float(coils.get())
I = float(current.get())
fieldmag = mu0*n*I
print fieldmag
calculate_button = Button(text='Calculate', command=solfield)
calculate_button.grid()
label_bfield = Label(text='B Field in +z Direction')
label_bfield.grid()
label_result = Label(text='solfield')
label_result.grid()
master.title('Coil Gun Simulation')
master.mainloop()
The problem is here:
calculate_button = Button(text='Calculate', command=solfield())
To pass the function solfield itself as the command, just use its name:
calculate_button = Button(text='Calculate', command=solfield)
What you're doing is calling the function, and then passing the return value of that function as the command.
Since you defined solfield above as do-nothing function, that return value is None, so you're telling calculate_button that its command=None, and it's properly doing nothing.
Meanwhile, as SethMMorton pointed out (but then deleted):
You have two functions named solfield, and you are naming a variable solfield in one of your solfield functions. Remove the empty function (the one with pass), and using a different variable name in the remaining function.
This isn't causing your actual problem, but it's certainly adding to the confusion that makes it harder for you to find the problem. (For example, if you hadn't included the excess empty definition of solfield at all, you would have gotten a NameError in the incorrect line, which would have made things easier to debug.)
Putting it all together, what you should do is:
Get rid of the empty (pass-only) definition of solfield.
Move the real implementation of solfield up above the point where you build the GUI.
Don't name a local variable solfield within the function.
Pass just solfield, not solfield() as the command for calculate_button.