so i have a simple problem but i have no idea what's wrong so have a look:
from tkinter import *
from time import sleep
root = Tk()
l1 = Label(root, text="Ok")
l1.pack()
sleep(5)
l2 = Label(root, text="Great")
l2.pack()
sleep(10)
l3 = Label(root, text="Nice")
l3.pack()
root.mainloop()
All i wanted to do is make a window, and then display those label's one after another so the window would pop up with just l1 and after 5s the l2 would also appear and then after another 5s l3 should show up. Instead i don't see this window at all for 10s and then it appear with all the label's at once. Can someone help me fix this ?
First of all, dont use from tkinter import *.
From this answer :
from Tkinter import * imports every exposed object in Tkinter into your current namespace. import Tkinter imports the "namespace" Tkinter in your namespace and import Tkinter as tk does the same, but "renames" it locally to 'tk' to save you typing
you want only one object of a module, you do from module import object or from module import object as whatiwantittocall
from module import * is discouraged, as you may accidentally shadow ("override") names, and may lose track which objects belong to wich module.
Now for your question, you need to use root.after(timeInMillisecond, functionToCall) and add the label in the function:
import tkinter as tk
root = tk.Tk()
button = tk.Button(root, text="Quit", command=root.destroy)
button.pack()
l1 = tk.Label(root, text="Ok")
l1.pack()
def add_label():
l1 = tk.Label(root, text="Ok")
l1.pack()
root.after(500, add_label)
root.after(500, add_label)
root.mainloop()
PS : if someone with 1500+ reputation could add a tags "root.after" or something like this, it's the main point of the question
Related
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
from tkinter import *
root = Tk()
mybutton = Button(root, text="Click Me!)
mybutton.pack
root.mainloop
I am using this code but still I am not able to see the button in the window
This code wouldn't execute neither pack method nor the mainloop because you are missing the parentheses when invoking functions. When you invoke functions without parentheses, you are only referencing to them instead of calling, so it means that the code inside the function will never be executed.
from tkinter import *
root = Tk()
mybutton = Button(root, text="Click me!")
mybutton.pack()
root.mainloop()
Modifying your code as shown above should solve your issue.
I am new to tkinter and have been using:
from tkinter import *
but have read this is bad practice.
I rewrote a very small bit of code to start using the following:
import tkinter as tk
However when I run the rest of the code. I get the error:
label.place(relx=0.4, rely=0.35, anchor=CENTER)
NameError: name 'CENTER' is not defined
root = tk.Tk()
label = tk.Label(root, text="I am a label widget")
label.place(relx=0.4, rely=0.35, anchor=CENTER)
button = tk.Button(root, text="I am a button")
label.pack()
button.pack()
root.mainloop()
Is this a namespace issue? How can I solve the problem?
* gets all the sub packages. Using import tkinter as tk just changes the name of the package from tkinter to tk.
You have not told your script CENTER is part of tkinter. (you did this automatically when you used *) but now you must do by explicitly telling CENTER is part of tkinter:
tk.CENTER
CENTER is a variable(actually they usually are referred to as constants) of tkinter module which equals to 'center'. So simply replace the line with:
label.place(..., anchor='center')
I am trying to learn Python and trying something GUI in Python and came across this Tkinter module. My code runs but the window does not appear when I run. My code is as follows:
from Tkinter import *
#to create a root window
root = Tk()
The program runs, gives no errors but the window does not show up.
Add this to your code root.mainloop(), Here's a tutorial.
In response to your comment
#Also note that `from <module> import *` is generally frowned upon
#since it can lead to namespace collisions. It's much better to only
#explicitly import the things you need.
from Tkinter import Tk, Label
root = Tk()
w = Label(root, text="Hello, world!")
w.pack()
root.mainloop()
As other answers have pointed out, you need to call mainloop on the root object.
I recommend an OO-style of programming, and I also recommend not doing a global import (ie: not 'from Tkinter import *').
Here's a template I usually start out with:
import Tkinter as tk
class ExampleView(tk.Frame):
def __init__(self, root):
tk.Frame.__init__(self, root)
l = tk.Label(self, text="your widgets go here...", anchor="c")
l.pack(side="top", fill="both", expand=True)
if __name__=='__main__':
root = tk.Tk()
view = ExampleView(root)
view.pack(side="top", fill="both", expand=True)
root.mainloop()
This makes it easy to keep your main logic at the start of the file, and keep the creation of the root and the calling of mainloop together, which I think makes the code a little bit easier to understand. It also makes reusing this code a little easier (ie: you could create a larger program where this is one of several windows that can be created)
Add root.mainloop() at the end.
Every time I use this code in my applications:
tkMessageBox.showinfo("Test", "Info goes here!")
a message box pops up (like it is supposed to), but after I click OK, the box disappears along with most of the other widgets on the window. How do I prevent the other widgets from disappearing?
Here Is My Code:
from Tkinter import *
import tkMessageBox
root = Tk()
root.minsize(600,600)
root.maxsize(600,600)
p1 = Label(root, bg='blue')
p1.place(width=600, height=600)
b1 = Button(p1, text="Test Button")
b1.place(x="30", y="50")
tkMessageBox.showinfo("Test", Info")
root.mainloop()
Ok, there are a few things going wrong here. First, your label has no string or image associated with it. Therefore, it's width and height will be very small. Because you use pack, the containing widget (the root window) will "shrink to fit" around this widget and any other widgets you pack in the root window.
Second, you use place for the button which means its size will not affect the size of the parent. Not only that, but you place the button inside the very tiny label. Thus, the only thing controlling the size of the parent is the label so the main window ends up being very small.
You have another problem is that you're showing the dialog before entering the event loop. I'm a bit surprised that it even works, but Tkinter sometimes does unusual things under the covers. You should enter the event loop before calling the dialog.
Try this variation of your code as a starting point:
from Tkinter import *
import tkMessageBox
def showInfo():
tkMessageBox.showinfo("Test","Info")
root = Tk()
p1 = Label(root, bg='blue', text="hello")
p1.pack()
b1 = Button(root, text="Test Button", command=showInfo)
b1.pack()
root.mainloop()