I thought that
from tkinter import *
imports all names into my current file's namespace so that I can access all of it directly. However, I get an error on instantiating a message box:
messagebox.showinfo("Something")
Once I add
from tkinter import messagebox
all works fine. I don't understand why. Didn't the first import statement already import all names in the tkinter module including messagebox?
Importing a module (tkinter) does not automatically import submodules (tkinter.messagebox) unless the module do it explicitly for you.
messagebox is a submodule of tkinter.
You should import module "messagebox"
(use "import ... as ..." to make it shorter)
import tkinter.messagebox
tkinter.messagebox.showinfo("Something")
Or as you figured out yourself,
from tkinter import messagebox
Since messagebox is a file inside the Tkinter module, you won't be able to access it by just calling Tkinter. To import the submodules you have to call out the specific files like this:
from tkinter import messagebox
Related
I have a Python script which generates a GUI window with tkinter library. I'd like to make some of it's buttons display a prompt - small window to ask the user for some number (something like in JavaScript). I tried the following command:
x = tkinter.simpledialog.askstring
But it returns an error:
NameError: name 'tkinter' is not defined
and no prompt is generated, although I have imported the library in the script's beginning:
from tkinter import *
from tkinter import simpledialog
Other elements (buttons, labels etc.) in the main window work correctly. Please help.
askstring is part of tkinter.simpledialog so you might import it like so
from tkinter.simpledialog import askstring
usage example
import tkinter as tk
from tkinter.simpledialog import askstring
root = tk.Tk()
x = askstring("Title", "Prompt")
print(x)
root.mainloop()
Here I am using from tkinter import * inside a function and when I am running the code it is showing me a SyntaxError.
Please tell me how I can use from tkinter import * inside a function.
You should move the import statements to the beginning of the file, at the top. You are also importing tkinter twice.
This question already has answers here:
Difference between import tkinter as tk and from tkinter import
(3 answers)
How do I import other Python files?
(23 answers)
Closed 4 years ago.
Can someone please explain the difference between
import tkinter as tk
and
from tkinter import *
It would be so great if someone could give and example where the same task is
achieved (or an object is created) by using these two statements seperately
Simply saying, the import tkinter as tk will initiate a tk instance of tkinter in your file which can call it's functions by writing something like
tk.Entry()
Which will save you from typing the long name.
while from tkinter import * will import all the names defined under the __all__ variable, so you can call the same function as
Entry()
You should read This to understand more
Both are importing the same package. The primary difference is that your first line is importing the package tkinter and then referring to it with "tk", which would allow you to call its functions using that different name. I don't have any experience with tkinter, but a good example I can give would be with numpy or pandas. A lot of functions in numpy, like numpy.random.randn() could instead be written with a shorthand name using "import as", like so:
import numpy as np
np.random.randn()
The differences seams little at first however import tkinter as tk is actually a much better option for one big reason.
By importing as something specific you make all the methods from that import required a prifix. This prevents methods from overriding or being overwritten accidentally.
For example if I have a library that contains a time() method and say lest call this library custom_timer and then say I need to import the built in time method also.
If use * for my import we have a problem.
from custom_timer import * # importing all modules including time() form this library.
import time # importing built in time().
What will end up happening is the 2nd import will override the time method from the first import. To prevent accidents like this we can simple import as your_prefix_here.
Take this example.
import custom_timer as ct # importing this library as ct.
import time # importing built in time().
In this case we will have 2 distinctive imports for time that do not override each other.
One is ct.time() and the other is time()
Because libraries like tkinter contain many methods it is safer to use import as verses import * for the above reason.
All that said if you are in a hurry and just want to throw something together to test an idea or answer a question using from tkinter import * is fine for much smaller applications. Personally I try to use import tkinter as tk for everything I do for good practice.
As for your request for 2 examples see below.
With tk import:
import tkinter as tk
root = tk.Tk()
tk.Label(root, text="I am a label made using tk prefix.")
root.mainloop()
With * import:
from tkinter import *
root = Tk()
Label(root, text="I am a label made in tkinter with the * import.")
root.mainloop()
I'm fairly new to python and looking for the best (most preferred) way to handle imports in a project.
I've been given the task to cleanup a python project and noticed there are the same includes in many modules throughout the project. Here is an example of what I am seeing.
File my_main_file.py
import os
import sys
import inspect
...
import gvars
import Common
...
from Tkinter import Menu
from Tkinter import WORD
from Tkinter import END
from Tkinter import Text
...
import menus.config
File gvars.py (also calls Tkinter)
from Tkinter import Text
from Tkinter import Tk
import Tkinter
File Common.py (also calls gvars and os)
import gvars
import tkFileDialog
import os
From Menus/config.py (also calls Common, gvars and Tkinter)
import Common
import gvars
import UIFunctions
import Tkinter
# Imports from Tk
from Tkinter import END
from Tkinter import Toplevel
from Tkinter import Button, Checkbutton
from Tkinter import Label
And on and on it goes... As you can see this is a mess I inherited. I know there are issue here (like "import blah" followed by "from blah import yuck"). I'm just looking for the most pythonic way to handle this.
Do I only need the imports in my_main_file.py? I.e. will Common.py code be able to access os. methods if "import os" is removed from the module and i=is only in the main script.
Is it best to have imports that are only referenced in a module imported in that module even though they are the similar? I.e. "from Tkinter import Text" in one module and "from Tkinter import END" in another.
Side question - which is better?
import Tkinter
or
from Tkinter import Menu
from Tkinter import WORD
from Tkinter import END
from Tkinter import Text
from Tkinter import Scrollbar
from Tkinter import Toplevel
from Tkinter import Button, Checkbutton
from Tkinter import Label
from Tkinter import Entry
from Tkinter import LEFT, RIGHT, TOP, BOTTOM
from Tkinter import DISABLED
from Tkinter import X, Y, BOTH
from Tkinter import VERTICAL, HORIZONTAL
from Tkinter import Listbox
from Tkinter import Frame, LabelFrame
from Tkinter import Entry
from Tkinter import N,S,E,W
from Tkinter import BROWSE, EXTENDED
from Tkinter import DISABLED, NORMAL
According to the PEP8 styleguide (one of the most authoritative sources on what is pythonic) using wildcard imports (from ... import *) should be avoided unless you are republishing an interface, which is not your intent.
My suggestion is to import TKinter as tk and refer to tk.WORD etc.
One of the reasons for doing this is that some of the constants and classes from Tkinter are fairly generically named - N, Button, etc.
By referring to tk.N, tk.Button, etc. it makes your intent in the code much clearer.
If one or two specific things are imported, then:
from Tkinter import END, Toplevel, ...
If pretty much everything in that module is imported, then:
from Tkinter import *
If more than a bunch of functions and classes are imported, then:
import Tkinter
Or more pythonic:
import Tkinter as tk
I am not sure if we can have common file to import all common modules. I think, for all of the files which you mentioned in question, you need to have separate imports.
About your side question, it is better to import specific function, method from class. You should import only those methods, functions which are being used in file. if you just do import Tkinter, then you have to use it like Tkinter.Menu, Tkinter.WORD etc in your code. Then it might be difficult to read if some library or module's functions have been used at lot of places in your file. So its better to import all required methods, functions from module and use them. You can import many functions from same library in one liner.
The way I've solved this in the past is to have an __init__.py file in each folder where the sources exist, then all your imports can go in there
There are even better ways of organizing python files. For more information on how to organize modules, see the official documentation
docs.python.org
stackoverflow
Also checkout importanize
Agree that from Tkinter import * is best avoided.
One way I found to deal with long imports on any given module. Not totally clean, but less wordy than the 1 per line repeats you have.
I would have done it with your TKinter import list, but I don't have it installed, so using sys instead.
#opening a parenthesis allows for implicit line feeds
from sys import (
stderr, stdout, stdin, #could have more...
#dont need this anymore
# maxint,
#maxsize, #dont this need anymore either
argv,
)
print globals().keys()
output:
['stdout', '__builtins__', '__file__', 'stdin', 'argv', '__package__', 'stderr', '__name__', '__doc__']
In my past programming i used the following code:
from tkinter import *
Gui = Tk()
but someone told me that importing * was not good for many reasons but now when i want to import
from tkinter import geometry
it says geometry not a module thing (name).
and when i do:
import tkinter
tkinter.geometry(500x500)
it says 'module' object has no attribute 'geometry'
Can someone explain me how to import with tkinter all the different ways?? Not only for geometry but most of the tkinter modules...???
That's because the module tkinter doesn't have a geometry function. It's the Tk instances that do.
Here's a good way to accomplish what you're trying to do:
import tkinter as tk # tk is a convenient, easy to type alias to use for tkinter.
gui = tk.Tk()
gui.geometry("500x500") # don't forget the quotes
Why from tkinter import * is a non-ideal way to import tkinter
As an aside, whoever told you that from tkinter import * was a bad idea was correct - when you do that, you load all of tkinter's namespace into your module's namespace.
If you do that, you can end up with unpleasant namespace collisions, like this:
from tkinter import *
gui = Tk()
Label = "hello"
Label1 = Label(gui, text=Label)
# Traceback (most recent call last):
# File "stackoverflow.py", line 98, in <module>
# Label1 = Label(gui, text=Label)
# TypeError: 'str' object is not callable
You've overwritten the reference to tkinter's Label widget - so you can't create any more Labels! Of course you shouldn't be capitalizing local variables like that anyways, but why worry about avoiding those namespace problems when you can do this instead:
import tkinter as tk
This ^^^^ import method is also preferable because if at some point you want to swap Tkinter out for another module with a similar implementation, instead of combing through your code for all elements of the Tkinter module, you can just go like this:
#import tkinter as tk
import newTkinter as tk
And you're all set. Or, if you want to use another module that happens to have some of the same names for its classes and methods, the following would cause chaos:
from tkinter import *
from evilOverlappingModule import *
but this would be fine:
import tkinter as tk
import evilOverlappingModule as evil
The reason that from module import * is considered harmful is that it pollutes the main namespace with every public name in the module. At best this makes code less explicit, at worst, it can cause name collisions. For example, module codecs has an open method defined, and there is the built-in version, which take different arguments. If I write
from codecs import *
f = open(…)
which open will I get? Tkinter has a lot of symbols, and tkinter based programs tend to use them very heavily. better than the import * is
import tkinter as tk
which then allows the — still explicit, but easier to type and read:
tk.Tk().geometry(…)
If you * imported tkinter, essentially tkinter. is in the namespace, meaning that to access to tkinter modules without worrying about prefixing it with tkinter.. In this case, geometry("500x500") is a method of Tk(), so you would use it like this
from Tkinter import *
Gui = Tk()
Gui.geometry("500x500")
Gui.mainloop()
Similar objects, such as various widgets, etc. are used the same. For example, a label would be made like this:
from Tkinter import *
Gui = Tk()
label= Label(Gui, text="Hello World!")
label.pack()
Gui.mainloop()
I don't know why someone said that importing * wasn't good cause that isn't true, it's actually better then just importing tkinter. Importing * will make the programming easier. With just tkinter you would need to type tkinter. before doing something, or if you do it as tk, you would need to do tk., from tkinter import * is the best what you can do.
Instead of doing:
from tkinter import *
You can do:
from tkinter import Tk, Canvas #The widgets you want to use
Or:
import tkinter as tk
Here’s a quick answer: Tkinter doesn’t have a geometry function. You can use the geometry function with instances of the Tk() class.
Example:
import tkinter as tk # Use the module name ’Tkinter’ if you have Python 2
root = tk.Tk()
root.geometry(‘500x500’) # You can change the size
# Other code goes here
root.mainloop()
Just like the geometry function, the mainloop, pack, grid, place, config etc. functions are used with the instances of the class Tk()
Thank You! Hope that works!