I'm trying to ad a label to a tkinter app, showing the procedure status, while doing something.
I don't want my window to stretch to follow the label size, so I used grid_propagate to apply this flag to the label and it's master, but this seems like is not working and the grid is moving, following the label size.
Here an example, following the same structure of my original program:
from tkinter import *
from tkinter import ttk
import threading
import time
def buttonManage():
label1.grid(columnspan=2, sticky=W)
threading.Thread(target=labelManage, name='LabelThread').start()
def labelManage():
while not label1.winfo_ismapped():
# Wait for graphic interface manager to draw, before removing resizing propagation from container frame
time.sleep(0.1)
label1.master.grid_propagate(False)
label1.grid_propagate(False)
for n in range(1, 100):
label1.configure(text=label1.cget('text') + 'a')
time.sleep(0.1)
label1.master.grid_propagate(True)
label1.grid_propagate(True)
window = Tk()
window.resizable(False, False)
tabControl = ttk.Notebook(window)
mainFrame = ttk.Frame(tabControl, padding='10 10 10 10')
optionFrame = ttk.Frame(tabControl, padding='10 10 10 10')
tabControl.add(mainFrame, text ='Backup')
tabControl.add(optionFrame, text ='Options')
tabControl.grid()
button = ttk.Button(mainFrame, text='Backup', command=buttonManage)
button.grid(columnspan=2, ipadx=70, ipady=20)
label1 = ttk.Label(mainFrame, text='')
window.mainloop()
Related
I am trying to place a label on top of a Frame, which is inside a 'Notebook' tab.
But when I run this code, the label always ends up in the center of the frame.
from tkinter import *
from tkinter import ttk
class Window:
def __init__(self,master):
self.master = master
master.title("Title")
master.resizable(1,1)
master.geometry('500x400')
self.load_UI()
def load_UI(self):
self.tabOptions = ttk.Notebook(self.master )
self.tab1 = Frame(self.tabOptions, padx=130, pady=80, bg='white')
self.tabOptions.add(self.tab1, text="Add Files")
self.tabOptions_AddFile()
self.tabOptions.pack()
def tabOptions_AddFile(self):
self.label = Label(self.tab1, text="Why is this in the center of the frame?")
self.label.grid(row=0, column=0)
root = Tk()
app = Window(root)
root.mainloop()
I tried to place the label using: pack(), grid(), place(). I also tried to place the label before adding the frame to the Notebook but it still looks the same :(
I am using python 3 btw.
This is because your Frame is padded in the line self.tab1 = Frame(self.tabOptions, padx=130, pady=80, bg='white'). Your Frame is here:
Just remove padx=130, pady=80 and all works. But to keep the size of tabOptions, replace
self.tabOptions.pack()
by
self.tabOptions.pack(fill=BOTH, expand=True)
I would like a text box to ask for input in a tkinter window, then use that input as a parameter to call a function that draws a Sierpinski triangle. My buttons work but my input box does not. I keep trying to fix my code but it is not working, any help would be appreciated.
import tkinter as tk
from tkinter import *
root = tk.Tk()
frame = tk.Frame(root)
frame.pack()
root.title('Fractals') #titles the button box
top_frame = tk.Frame()
mid_frame = tk.Frame()
prompt_label = tk.Label(top_frame, \
text='Enter a number of iterations (more is better):')
iterations = tk.Entry(root,bd=1)
itr=iterations.get()
itr=int(itr)
button = tk.Button(frame,
text="QUIT",
fg="red",
command=quit)
button.pack(side=tk.LEFT)
sTriangle = tk.Button(frame,
text="Triangle",
command=lambda: sierpinski(fred, (-500,-500), (500,-500),
(0,500),itr))
sTriangle.pack(side=tk.LEFT)
fsquare = tk.Button(frame,
text="Square",
command=fractalsquare(fred,(-500,-500),(500,-500),
(500,500),(-500,500),itr))
fsquare.pack(side=tk.LEFT)
root.mainloop()
There are several issues:
1) Choose one way to import tkinter or confusion will result
2) You should provide a master for your Frames and then pack them. Pay attention on where the frames appear and what they contain.
3) It's usual to assign a textvariable to the Entry which will contain what you enter into it. The textvariable should be a tk.StringVar.
4) If a Button has a callback function, it must be defined before you create the button.
5) The variable fred is not defined.
Example of how you can write it:
import tkinter as tk
root = tk.Tk()
root.title('Fractals') #titles the button box
# Create the Label at the top
top_frame = tk.Frame(root) # Top Frame for
top_frame.pack()
prompt_label = tk.Label(top_frame,
text='Enter a number of iterations (more is better):')
prompt_label.pack()
# Create the Entry in the middle
mid_frame = tk.Frame(root)
mid_frame.pack()
itr_string = tk.StringVar()
iterations = tk.Entry(mid_frame,textvariable=itr_string)
iterations.pack()
fred=None # Was not defined...
# Create Buttons at the bottom
bot_frame = tk.Frame(root)
bot_frame.pack()
button = tk.Button(bot_frame, text="QUIT", fg="red", command=quit)
button.pack(side=tk.LEFT)
def sierpinski(*args): # sTriangle button callback function
itr = int(itr_string.get()) # How to get text from Entry
# if Entry does not contain an integer this will throw an exception
sTriangle = tk.Button(bot_frame, text="Triangle",
command=lambda: sierpinski(fred, (-500,-500), (500,-500),(0,500),itr_string))
sTriangle.pack(side=tk.LEFT)
def fractalsquare(*args): pass # fsquare button callback function
fsquare = tk.Button(bot_frame, text="Square", command=fractalsquare(fred,
(-500,-500),(500,-500),(500,500),(-500,500),itr_string))
fsquare.pack(side=tk.LEFT)
root.mainloop()
You should seriously study a basic tkinter tutorial. Try this one: An Introduction To Tkinter
When I increase the size of the font using following code, it also increase the size of the widget. Is it possitlbe to increase font size by keeping the size of the text widget constant?
Thank You
A11 = tkinter.Text(top, height=28, width=70,background = "#02e0a1")
labelfont = ('times', 20, 'bold')
A11.config(font = labelfont)
If you force the GUI window to be a specific size, then changing the font of a text widget won't cause the text widget to grow*. It usually helps to set the width and height of the text widget to 1 (one) so that it won't even try to grow when you change the font.
well, the widget will try to grow, but the size constraint on the window will prevent the widget from getting too big.
Here's a simple contrived example.
import tkinter as tk
import tkinter.font as tkFont
class Example(object):
def __init__(self):
root = tk.Tk()
self.font = tkFont.Font(family="helvetica", size=18)
text = tk.Text(root, width=1, height=1, font=self.font)
button = tk.Button(root, text="Bigger", command=self.bigger)
button.pack(side="top")
text.pack(side="top", fill="both", expand=True)
text.insert("end", "Hello, world!")
# force the widow to a specific size after it's created
# so that it won't change size when we change the font
root.geometry("800x400")
def start(self):
tk.mainloop()
def bigger(self):
size = int(self.font.cget("size"))
size += 2
self.font.configure(size=size)
app = Example()
app.start()
The same technique can work on a smaller scale by putting the size constraint on a frame rather than the root window. If you put the text widget inside a frame, turn geometry propagation off, and then give the frame a fixed size, the widget will not grow. This is one of the few times when turning geometry propagation off can be useful.
Here's a modification of the above example, using this technique:
import tkinter as tk
import tkinter.font as tkFont
class Example(object):
def __init__(self):
root = tk.Tk()
self.font = tkFont.Font(family="helvetica", size=18)
button = tk.Button(root, text="Bigger", command=self.bigger)
# create a frame for the text widget, and let it control the
# size by turning geometry propagation off
text_frame = tk.Frame(root, width=800, height=400)
text_frame.pack_propagate(False)
text = tk.Text(text_frame, width=1, height=1, font=self.font)
text.pack(side="top", fill="both", expand=True)
button.pack(side="top")
text_frame.pack(side="top", fill="both", expand=True)
text.insert("end", "Hello, world!")
def start(self):
tk.mainloop()
def bigger(self):
size = int(self.font.cget("size"))
size += 2
self.font.configure(size=size)
app = Example()
app.start()
Widget size is determined by font size, so width=10 for a small font is smaller than width=10 for a large font. The following code only changes the font size.
import sys
if sys.version_info[0] < 3:
import Tkinter as tk ## Python 2.x
else:
import tkinter as tk ## Python 3.x
class DifferentFonts():
def __init__(self):
self.top=tk.Tk()
tk.Label(self.top, text="Small Font", width=10, bg="lightblue",
font=('DejaVuSansMono', 10)).grid(row=1)
tk.Label(self.top, text="Large Font", width=10, bg="lightyellow",
font=('DejaVuSansMono', 30)).grid(row=2)
tk.Button(self.top, text="Quit", bg="orange",
command=self.top.quit).grid(row=20)
self.top.mainloop()
DifferentFonts()
I would like for a cant afford label to appear then after a second disappear when i push a button to buy something. It seems like the time.sleep(1) is making it not work properly. This is done on python tkinter.
def buttonpressed():
Label.place(x = 500, y = 500 #where i want the label to appear
time.sleep(1)
Label.place(x = 10000, y = 10000) #moving it away where i wont be able to see it
You can't use sleep because it stops mainloop
You can use root.after(time_in_milliseconds, function_name) to run function
Example
import tkinter as tk
def button_pressed():
# put text
label['text'] = "Hello World!"
# run clear_label after 2000ms (2s)
root.after(2000, clear_label)
def clear_label():
# remove text
label['text'] = ""
root = tk.Tk()
label = tk.Label(root) # empty label for text
label.pack()
button = tk.Button(root, text="Press Button", command=button_pressed)
button.pack()
root.mainloop()
If you have to create and remove label then use label.destroy()
import tkinter as tk
def button_pressed():
label = tk.Label(root, text="Hello World!")
label.pack()
root.after(2000, destroy_widget, label) # label as argument for destroy_widget
def destroy_widget(widget):
widget.destroy()
root = tk.Tk()
button = tk.Button(root, text="Press Button", command=button_pressed)
button.pack()
root.mainloop()
And shorter version without destroy_widget
import tkinter as tk
def button_pressed():
label = tk.Label(root, text="Hello World!")
label.pack()
root.after(2000, label.destroy)
root = tk.Tk()
button = tk.Button(root, text="Press Button", command=button_pressed)
button.pack()
root.mainloop()
Press button many times to see many labels which disappear after 2s.
You can use after() to set up a callback after a specified interval. In the callback function clear the label with pack_forget() (or grid_forget() if you're using grid). This is better than setting the label's text attribute to an empty string because that causes widgets to be resized, which might not be what you want. Here's an example:
import Tkinter as tk
class App():
def __init__(self):
self.root = tk.Tk()
self.label = tk.Label(text='I am a label')
self.label.place(x=0, y=0)
self.label.after(1000, self.clear_label) # 1000ms
self.root.mainloop()
def clear_label(self):
print "clear_label"
self.label.place_forget()
app=App()
Another option is to use self.label.destroy() to destroy the widget, however, pack_forget() allows you to display the label again by calling pack() on the widget again.
# I made it through calling 2 functions:
from tkinter import *
root = Tk()
root.geometry('400x200') # width by height
def one_text():
label['text'] = "Look around"
root.after(1000, another_text)
def another_text():
label['text'] = "and smile"
root.after(1000, one_text)
label= Label(root ,font=('Helvetica', 14), fg='black', bg='white')
label.pack()
one_text()
root.mainloop()
Is it possible to code time HH:MM:SS using text widget?
I know we can do this with label widget. My code deals with text widget and want to display time at any corner on the TKinter window.
If possible how to delete and insert the text using label widgets. Text widget has the following methods default.
delete(startindex [,endindex])
This method deletes a specific character or a range of text.
insert(index [,string]...)
This method inserts strings at the specified index location.
In my code the text has to be deleted and inserted all the time.
thanks.
delete from 1.0 to end.
import datetime
text.delete('1.0', 'end')
text.insert('end', datetime.datetime.now().strftime('%H:%M:%S')) # text.insert('end', label['text'])
label['text'] = datetime.datetime.now().strftime('%H:%M:%S')
Display Entry on bottom right
import datetime
from Tkinter import * # from tkinter import * # Python 3.x
root = Tk()
root.geometry('500x500')
frame = Frame(root)
frame.pack(side=BOTTOM, fill=BOTH)
entry = Entry(frame)
entry.pack(side=RIGHT)
entry.insert(END, datetime.datetime.now().strftime('%H:%M:%S'))
root.mainloop()
def __init__(self):
tk.Tk.__init__(self)
self.geometry("1360x750")
frameLabel = tk.Frame(self)
self.text = tk.Text(frameLabel)
frameLabel.pack(side=BOTTOM, fill=BOTH)
self.text.pack(side=RIGHT)
self.text.insert('end', 'TEST')
self.queue = Queue.Queue()
thread = SerialThread(self.queue)
thread.start()
self.process_serial()
UPDATE2
import datetime
from Tkinter import * # from tkinter import * # Python 3.x
root = Tk()
root.geometry('500x500')
frame = Frame(root)
frame.pack(side=BOTTOM, fill=BOTH)
label = Label(frame)
label.pack(side=RIGHT)
label['text'] = datetime.datetime.now().strftime('%H:%M:%S')
root.mainloop()