tkinter.messagebox.showinfo doesn't always work - python

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.

Related

Why do I get the error: nameError: name tk is not defined, while I definded name tk?

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)

I'm getting a NameError saying name 'Tk' is not defined when I'm trying to use Tkinter on VsCode

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

Creating and referencing an object made with different class (type Gtk.Overlay) within window class (Gtk.Window) causes runtime error

This is the code:
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk
class MyAnime(Gtk.Label):
def __init__(self):
pass
class MyWindow(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title="Hello World")
self.label = MyAnime()
self.add(self.label)
win = MyWindow()
win.connect("destroy", Gtk.main_quit)
win.show_all()
Gtk.main()
This is the error that pops up:
Traceback (most recent call last):
File "fixing.py", line 19, in <module>
win = MyWindow()
File "fixing.py", line 16, in __init__
self.add(self.overlay)
RuntimeError: object at 0x7f055a193c80 of type MyAnime is not initialized
Of course in this example I could just create a Gtk.Label within MyWindow. But for my actual code, I am trying to create an object based on a class of type Gtk.Overlay from within the MyWindow class.
I'm confused as (to my understanding) the object is already initilized in self.label = MyAnime() but the runtime error says otherwise (I feel as though I am missing something very obvious :/)
EDIT: Progmatico's solution of replacing pass with super().__init__() worked although from looking at the runtime error and some source code from the GNOME files app, I found you can also use Gtk.Label.__init__(self)

python program using tkinter wont run due to a tclError

I'm trying to learn how to make a GUI with tkinter the conde is rather basic but I get the following error:
Exception has occurred: TclError
no display name and no $DISPLAY environment variable
File "/home/josh/Documents/VSC/python/SECOM/mainWindow.py", line 7, in __init__
self.wind = Tk()
File "/home/josh/Documents/VSC/python/SECOM/mainWindow.py", line 12, in <module>
MW = mainWindow()
When I google such error there is only answer for raspberry pi or remote servers and stuff. Im just using ubuntu(20.04) and have a conda (4.8.3) venv with python (3.8). I'm also using VSC and have the venv as interpreter in VSC. HELP :c
MainWindow.py
from tkinter import ttk
from tkinter import *
class mainWindow:
def __init__(self):
self.title = "SECOM"
self.wind = Tk()
self.wind.title(self.title)
if __name__ == '__main__':
MW = mainWindow()
window.mainloop()
You are talking a lot about windows in your code, but not much of anything is actually a window. Some of it is nothing, at all. Try This.
import tkinter as tk
class Root(tk.Tk):
def __init__(self, **kwargs):
tk.Tk.__init__(self, **kwargs)
#PUT YOUR APP HERE
if __name__ == '__main__':
root = Root()
root.title("SECOM")
root.mainloop()
Here are the problems with your script
from tkinter import ttk
#importing like this pollutes your namespace
from tkinter import *
class mainWindow:
def __init__(self):
#there is no reason to store a reference to the title
self.title = "SECOM"
#why are you burying your root in a class property
self.wind = Tk()
#this is why you don't need a reference to title
self.wind.title(self.title)
if __name__ == '__main__':
#sure
MW = mainWindow()
#window? window where? You buried this in MW.wind
window.mainloop()

Tkinter name "X" is not defined error.

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.

Categories

Resources