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!
Related
Question 1: I have a non useful window that appears when using tkinter in spyder.
Any solution for this issue ?
Question 2: Why there is a warning message on 'from tkinter import *' ?
Code:
from tkinter import *
from tkinter.simpledialog import askstring
from tkinter import messagebox
box = Tk()
name = askstring('Name','What is your name?')
messagebox.showinfo('Hello!','Hi, {}'.format(name))
box.mainloop()
The "non useful" window is simply box.
messagebox will open a new window. So you can just remove box if you don't intend to use it further.
It's usually not recommended to import everything from a module because it could cause name conflicts with other modules or built-in function:
import tkinter as tk
from tkinter.simpledialog import askstring
name = askstring('Name','What is your name?')
tk.messagebox.showinfo('Hello!','Hi, {}'.format(name))
The additional window is the instance of Tk most often named root cause every other window or widget is a child of the root window. You will need it to initiate your messagebox but if you don't want to look at it you have several choices.
My personal recommendation is to us overrideredirect which will discard it from the taskbar and use withdraw to actually hide it in the screen/monitor. But you may prefer wm_attributes('-alpha', 0) over it to make it opaque/transparent.
Avoiding wildcard imports is recommanded because of name clashes/collisions. For example tkinter has a PhotoImage class, so does pillow. If you have wildcard imports on both, on PhotoImage will overwrite the other in the global namespace.
Code:
import tkinter as tk
from tkinter.simpledialog import askstring
from tkinter import messagebox
box = tk.Tk()
box.overrideredirect(True)
box.withdraw()
name = askstring('Name','What is your name?') #blocks the code block
messagebox.showinfo('Hello!','Hi, {}'.format(name)) #shows message
box.after(5000, box.destroy) #destroy root window after 5 seconds
box.mainloop()#blocks until root is destroyed
For the first question answer is that you don't need to create box because function askstring create frame on it's own. So if the whole program is just to ask for the name and to greet user, you are perfectly fine with just this piece of code:
from tkinter import *
from tkinter.simpledialog import askstring
from tkinter import messagebox
name = askstring('Name','What is your name?')
messagebox.showinfo('Hello!','Hi, {}'.format(name))
And for the second question you need to post what warning you get.
Hi I'm new to python and Tkinter. When I execute the code, nothing is happening an there isn't error. After less than one second,the code finish to process.
from tkinter import *
w1 = Tk()
w1.mainloop'
First of all, you used
from tkinter import *
so tkinter.Tk isn't a thing, since tkinter isn't in the namespace, instead you must just do Tk
Also, tkinter.Tk is a class, and for it to work, needs to be instantiated. w1.mainLoop is a function, and needs to be called.
Therefore, a working code should be
from tkinter import *
w1 = Tk()
w1.mainloop()
I believe you already fixed your typo w1.mainloop' to w1.mainloop().
I want to recommend using import tkinter as tk, so you don't overwrite you namespace.
Then your code could look like this:
import tkinter as tk
w1 = tk.Tk()
w1.mainloop()
I have some general questions regarding working code below:
tkinter is library for graphic interface as I understand I can use it interchangeably with for example Kivy?
Would it be better to learn Kivy instead or other?
Lines import tkinter as tk and from tkinter import * do exactly the same, in the first one I have alias though?
In the code below, why do I have to use ttk in ttk.Progressbar?
I imported whole library with import tkinter as tk so why do i have to reimport ttk just for progress bar? (otherwise it is not working). I would expect to work sth. like tk.Progressbar
In the line btnProg = tk.Button(self.root, text = 'update', command=self.fnUpdateProgress), why method "fnUpdateProgress" can't have any variables? Whenever I add any, the button stop working? -> for example btnProg = tk.Button(self.root, text = 'update', command=self.fnUpdateProgress(24)) (ofc then some changes in def of the method itself)
I created progress bar (pb) as attribute of the class Test, but wolud it be better to define it as regular variable (without self)? To be honest, code works exactly the same.
Code:
import tkinter as tk
from tkinter import *
from tkinter import ttk
from CreateProgramMain import main
import GlobalVariables
class Test():
####################################################################################
def __init__(self):
self.Progress=0
self.root = tk.Tk()
self.root.title(GlobalVariables.strAppName)
self.root.geometry('400x200')
lbl = Label(self.root, text="Please choose environment.",font=("Arial Bold", 12))
lbl.grid(column=2, row=0,sticky='e')
def btnTestClicked():
main("TEST",self)
btnTest=tk.Button(self.root, text="Test Environment", command=btnTestClicked)
btnTest.grid(column=2, row=15)
#Place progress bar
pb = ttk.Progressbar(self.root,orient='horizontal',mode='determinate',length=200)
pb.grid(column=1, row=65, columnspan=2, padx=10, pady=20)
pb["value"]=self.Progress
pb["maximum"]=100
btnProg = tk.Button(self.root, text = 'update', command=self.fnUpdateProgress)
btnProg.grid(column=2, row=75)
self.root.mainloop()
def fnUpdateProgress(self): #why i cant insert variable inside?
pb["value"]=self.Progress
self.Progress=self.Progress+5
pb.update()
app = Test()
Thank you
it is upto you. However, tkinter and kivy both have their own syntaxes, commands, and their own usages. It might be a little difficult to convert tkinter code to kivy.
it is upto you
Yes. In the first, you have imported tkinter as tk. In the second one. You have done a wild card import. You have imported everything
Tkinter is a folder containing various modules. It contains a file called ttk.py which you have to import to access ttk.
All other classes like Label, Entry, Tk is present in __init__.py
you have to use lambda for it. If you call the function, it will be executed wlright away and the returned value is kept as the command.
Doing command=self.fnUpdateProgress(24)) will execute the function right away. Then, the returned value is kept as a command. Here, it returns None. So the command is nothing or the button is useless.
Use a lambda expression command=lambda: self.fnUpdateProgress(24))
if you don't add self it will be local to the function only. To access ot outside, it would have to be declared global, which is the point to avoid while using classes
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 use Tkinter gui library for python . when we come to create root main window we write
root=Tk()
I want to undetstand what happens inside Tk() , so how to know the attributes and function ?
(Python3)
Import Tk, then call dir or help:
>>> import tkinter as tk
>>> help(tk.Tk)
<lots of useful information>