I am trying to take a more object oriented approach by using classes, but I seem to be getting the following error.
Traceback (most recent call last): File "./Main.py", line 17, in
Main = Menu(root) File "./Main.py", line 11, in init
self.F1.pack(fill=X) NameError: global name 'X' is not defined
Here is the code I am trying to compile, I have broken it down to a simple snippet to show the error I am getting:
#!/usr/bin/python
import Tkinter as tk # Python 2 import
class Menu:
def __init__(self, parent):
self.root = parent
self.root.geometry("800x400")
self.root.title("Image Compression")
self.F1 = tk.Frame(self.root, bg="black")
self.F1.pack(fill=X)
if __name__ == "__main__":
root = tk.Tk()
Main = Menu(root)
root.mainloop()
Your
self.F1.pack(fill=X)
should be
self.F1.pack(fill=tk.X)
and you should also add expand=True to make the fill actually work.
Tkinter.X and Tkinter.Y and Tkinter.BOTH are constants (strings) that are defined in the Tkinter module. Without the Tkinter., you are trying to access X as a variable.
Your line should read
self.F1.pack(fill=tk.X, expand=True)
to do what you want it to do.
Oh, one more afterthought... You may be thinking, "Hey! I've seen .pack(fill=X) working before!" This is true when there is a
from Tkinter import *
statement above the reference. Then, in that instance, X would be found as coming from Tkinter but without needing the leading Tkinter.. That's the topic of namespace, which is beyond the scope of this answer.
Related
I am making a code editor. But when I type in my code editor the following code, it is getting a NameError.
import tkinter as tk
class App(tk.Tk):
def __init__(self):
super().__init__()
self.label = tk.Label(self, text="iets") # here, tk isn't recognized
self.label.pack()
app = App()
app.mainloop()
All the code of the input tkinter text widget is executed by a exec statement. The whole NameError is:
Traceback (most recent call last):
File "C:\Users\Gebruiker\PycharmProjects\mylanguage\execute.py", line 24, in do
exec(self.input)
File "< string>", line 9, in
File "< string>", line 6, in __ init__
NameError: name 'tk' is not defined
Why do i get this error? in the code I typed in I do have import tkinter as tk!
The hierarchy of my project is the following:
I've 8 files: main.py, execute.py, output.py et cetera
From main.py, the tkinter app is created.
When i press button run, in execute.py the code is, as it says, executed.
Then the output or error is being displayed in a toplevel window from the file output.py.
execute.py:
...
def do(self):
sys.stdout.write = output
try:
set_last("")
exec(self.input) #line 24
except Exception:
set_last("text.config(foreground='red')")
error = traceback.format_exc()
output(error)
...
when i add print(repr(self.input)) on top of do() it outputs:
import tkinter as tk
class App(tk.Tk):
def __init__(self):
super().__init__()
self.label = tk.Label(self, text="iets")
self.label.pack()
app = App()
app.mainloop()
See the whole project on github: https://github.com/keizertje/myl
thanks in advance!
You file execute.py permits someone to exec() arbitrary code (here be dragons). In this case, the code includes an alias tk that is unknow in the context of execute.py.
Either execute.py needs to import and set this alias or the text file contents of self.input needs to do that.
For example:
import statistics
text = """
print(statistics.mean([1,2]))
"""
exec(text)
or
text = """
import statistics
print(statistics.mean([1,2]))
"""
exec(text)
If yourtext is your class, then this seems to work for me:
text = """
import tkinter as tk
class App(tk.Tk):
def __init__(self):
super().__init__()
self.label = tk.Label(self, text="iets")
self.label.pack()
app = App()
app.mainloop()
"""
exec(text)
sorry for the consternation, the reason of my problem was totally other than i expected! the problem was that when i put self.input in exec() the program starts with all global variables. how to fix? as acw1668 said: simply use exec(self.input, {}) and it worked! this empty dict means that at the start of executing there are no global variables.
so do() becomes:
def do(self):
sys.stdout.write = output
try:
set_last("")
exec(self.input, {}) # here it's fixed!
except Exception:
set_last("text.config(foreground='red')")
error = traceback.format_exc()
output(error)
When I'm trying to run a script to see if I can use tkinter on VsCode it throws a NameError saying name 'Tk' is not defined. Furthermore I can run it on IDLE and it runs just fine. I've been searching around to see if I can fix it but I still can't get it working. Do you have any idea what I'm doing wrong?
Here is the code:
from tkinter import *
root = Tk()
myLabel = Label(root, text = 'Hello World!')
myLabel.pack()
Do NOT name your file tkinter.py because the tkinter module you are trying to import is actually importing the file itself. And since there's no function called Tk in your file, you are getting that error. Rename the file to something else.
For example, rename it to gui.py.
Also, it's better to be explicit rather than implicit in python. So instead of
# Pollutes your namespace
# May clash with the functions you define or functions of other libraries that you import
from tkinter import *
root = Tk()
...
you should use
import tkinter as tk
root = tk.Tk()
...
Here's an example of how it can clash with other namespaces:
from tkinter import *
root = Tk()
Label = "hello"
Label1 = Label(gui, text=Label)
This results in an error:
Traceback (most recent call last):
File "stackoverflow.py", line 98, in <module>
Label1 = Label(gui, text=Label)
TypeError: 'str' object is not callable
from tkinter import*
root = Tk()
shape = Canvas(root)
class GUI():
def __init__(self):
pass
def create_button(self, info, boom, posit):
self.Button(root)
self.config(text=info)
self.bind("<Button-1>",boom)
self.grid(column=posit[0],row=posit[1])
def create_label(self, info, posit):
self.Label(root)
self.config(text=info)
self.grid(column=posit[0],row=posit[1])
def go_away(self):
print("GO AWAY before")
self.button.grid_forget()
print("GO AWAY")
def make_GUI():
root.title("Hexahexaflexagon")
hexahexa = GUI()
quit_butt = GUI()
quit_butt.create_button("Exit","root.destroy()",[0,1])
quit_butt.go_away()
make_GUI()
root.mainloop()
Okay so I am trying to write a class function to just hide (and if not that then delete) a button created by tkinter, I'm new to classes and the error message I keep getting is that the GUI class does not have that function or that object does not have that attribute, I've tried code such as frm.forget(), .lower(), .grid_forget() but there not working for me.
The traceback is:
Traceback (most recent call last):
File "N:\HW\Hexahexaflexagon generator.py", line 94, in <module>
make_GUI()
File "N:\HW\Hexahexaflexagon generator.py", line 63, in make_GUI
quit_butt.go_away()
File "N:\HW\Hexahexaflexagon generator.py", line 51, in go_away
self.button.grid_forget()
AttributeError: 'function' object has no attribute 'grid_forget'
The problem is this line:
self = Button(root)
You are redefining self from referring to the current object, to now refer to a different object. You have the same problem further down with a label. This is simply not how python works.
You must store the widgets as attributes on self, not as self itself.
self.button = Button(root)
...
self.label = Label(root)
Once you do that, you can hide the button or label with grid_forget since you're using grid to make it visible:
self.button.grid_forget()
You have another problem in that you're passing in a command as a string. This will not work the way you think it does. If you want to be able to pass in a function, it needs to be a reference to an actual function:
quit_butt.button("Exit",root.destroy,[0,1])
I have just started working with Python's tkinter GUI tool. In my code I create an simple GUI with one button and I want to show the user a messagebox if they click on the button.
Currently, I use the tkinter.messagebox.showinfo method for it. I code on a Windows 7 computer using IDLE. If I run the code from IDLE everything works fine, but if I try to run it standalone in the Python 3 interpreter it doesn't work any more. Instead it logs this error to the console:
AttributeError:'module' object has no attribute 'messagebox'
Do you have any tips for me? My code is:
import tkinter
class simpleapp_tk(tkinter.Tk):
def __init__(self,parent):
tkinter.Tk.__init__(self,parent)
self.parent = parent
self.temp = False
self.initialize()
def initialize(self):
self.geometry()
self.geometry("500x250")
self.bt = tkinter.Button(self,text="Bla",command=self.click)
self.bt.place(x=5,y=5)
def click(self):
tkinter.messagebox.showinfo("blab","bla")
if __name__ == "__main__":
app = simpleapp_tk(None)
app.title('my application')
app.mainloop()
messagebox, along with some other modules like filedialog, does not automatically get imported when you import tkinter. Import it explicitly, using as and/or from as desired.
>>> import tkinter
>>> tkinter.messagebox.showinfo(message='hi')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'messagebox'
>>> import tkinter.messagebox
>>> tkinter.messagebox.showinfo(message='hi')
'ok'
>>> from tkinter import messagebox
>>> messagebox.showinfo(message='hi')
'ok'
This is case sensitive - tkinter should be Tkinter wherever it is used. I did this and was able to run your example.
I'm learning python and encountering issues with what appears to be class decorators from tkinter. I can get tkinter to work as long as I never try to decorate with Frame. The code below gives me no errors, and no window. For whatever reason, the class I define, never gets defined. Below is my code. Below that is testing i've done based on similar questions regarding tkinter.
>>> from tkinter import *
import tkinter
class Apples:
def __init__(self, master):
frame = Frame(master)
frame.pack()
self.button = Button(frame, text="Quit", fg="blue", command=frame.quit)
self.button.pack(side=LEFT)
self.hellos = Button(frame, text="Hello", command=self.say_hello)
self.hellos.pack(side=LEFT)
def say_hello(self):
print("Hello World!")
root = Tk()
app = Apples(root)
root.mainloop()
No window shows up. No error. So I check on the class...
>>> test = Apples(root)
Traceback (most recent call last):
File "<pyshell#54>", line 1, in <module>
test = Apples(root)
NameError: name 'Apples' is not defined
>>>
I found a similar question Creating buttons with Python GUI and attempted the code from pythonMan. I still am encountering the same class declaration issue.
>>> from tkinter import *
class Application(Frame):
"""A GUI application with three button"""
def __init__(self,master):
self.master = master
self.create_widgets()
def create_widgets(self):
#"""Create three buttons"""
#Create first buttom
btn1 = Button(self.master, text = "I do nothing")
btn1.pack()
#Create second button
btn2 = Button(self.master, text = "T do nothing as well")
btn2.pack()
#Create third button
btn3=Button(self.master, text = "I do nothing as well as well")
btn3.pack()
root = Tk()
root.title("Lazy Button 2")
root.geometry("500x500")
app = Application(root)
root.mainloop()
>>> Application
Traceback (most recent call last):
File "<pyshell#58>", line 1, in <module>
Application
NameError: name 'Application' is not defined
>>>
I can think something is not being declared properly, but is not generating a syntax error. Any help would be greatly appreciated.
I think you don't need an ">>>" sign.
"from Tkinter import *"
Assuming your code is properly reproduced in the second part of your question, you're defining your class incorrectly. You have def __init__ at the same level of indentation as class Application(Frame). Your methods need to be indented for them to be part of the class.
The code in the first part of your question works fine for me.