I want to update the label of a Tkinter LabelFrame widget.
For a Label widget, this can be done using the textvariable attribute, to which one can assign a StringVar.
I want to do the same thing, but for a LabelFrame
self.labelText = StringVar()
self.selectionFrame = ttk.LabelFrame(self, textvariable=self.labelText)
(...)
if A:
self.labelText.set("LabelA")
elif B:
self.labelText.set("LabelB")
How can I achieve this?
You can't. Neither the Tkinter LabelFrame nor the ttk LabelFrame support associating a variable with the widget.
If what you're really asking is how can you change the label, then you can use the configure method:
self.selectionFrame.configure(text="hello")
I just found some kind of a solution - using the labelwidget attribute to supply a separate Label object which uses the underlying StringVar:
self.labelText = StringVar()
self.labelWidget = Label(self, textvariable=self.labelText)
self.selectionFrame = ttk.LabelFrame(self, labelwidget=self.labelWidget)
This way, I can update the labelText to change the label of the LabelFrame
self.labelText.set("New Label")
I found that there is a problem to set a new label text due to text length.
So, I recommend that define a width of labelwidget as mentioned below:
self.labelWidget = Label(self, textvariable=self.labelText, width = 20)
Related
I have a window containing widgets with a grid layout, created by this code:
from tkinter import *
window = Tk()
label = Label(text="that label")
label.grid(row=0, column=0, sticky='EW')
entry = Entry()
entry.grid(row=1, column=0, sticky='EW')
window.mainloop()
I would expect the label and entry widget to resize with the window, but if I enlarge the window, it looks like this:
If I use pack instead of grid (with the fill option) like so:
from tkinter import *
window = Tk()
label = Label(text="that label")
label.pack(fill=X)
entry = Entry()
entry.pack(fill=X)
window.mainloop()
Then the enlarged window looks like this (what I would want it to look like):
Why don't the widgets resize with the window when using grid and how do I make them do it?
As to why the grid geometry manager doesn't do this automatically - I don't really know. Maybe someone can elaborate on this?
But the solution is very simple: Using grid_columnconfigure (or grid_rowconfigure respectively):
This is a function associated with a frame/window object that takes as parameters the column (or row) it modifies (can also be a list of indices or the keyword all for all columns/rows) and parameters to configure (see the documentation for a detailed description).
To get the widgets to resize with their master object, the parameter weight has to be set to a nonzero value. Your example would look like this:
from tkinter import *
window = Tk()
label = Label(text="that label")
label.grid(row=0, column=0, sticky='EW')
entry = Entry()
entry.grid(row=1, column=0, sticky='EW')
window.grid_columnconfigure(0, weight=1)
window.mainloop()
If you run the code the label and entry widget will change size accordingly:
Note that if you use different values for weight for different columns/rows, their relation will determine how the extra space gets split up between them.
Working on a unit converter using Tkinter python, I want to change all other units according to the input unit but can't able to call that function which later configures other labels of units.
mainEntry = Entry(width=15,font="arial 15 bold")
mainEntry.grid(row=0,column=0)
This Entry will get the input from user and other labels get update according to input without clicking any button.
Set a variable to Entry widget and use the trace method to detect any changes in the text and update labels accordingly.
Here is an example:
from tkinter import *
def change_lbl(*args):
lbl['text']=var.get()
root = Tk()
var = StringVar()
var.trace('w', change_lbl)
lbl = Label(root, text='Hello')
lbl.pack()
entry = Entry(root, textvariable=var)
entry.pack()
root.mainloop()
I am trying to set the option selected in the dropdown of a combobox as a variable, however, the label I am using to represent the variable is currently just reading .!combobox . For example if I selected 'Customer 2' from the dropdown , the label would change to customer 2. I may need to use a button to do this but I am unsure how to make that work.
import tkinter as tk
from tkinter import ttk
root = tk.Tk()
ICus = tk.StringVar(root)
ICus.set("Select Customer")
ICustomer = ttk.Combobox( textvariable = ICus, state = 'readonly')
ICustomer['values'] = ("Customer1", "Customer2", "Customer3")
ICustomer.grid(row = 2, column = 2)
label_ICustVar = tk.Label( text= ICustomer)
label_ICustVar.grid(row = 3, column = 3)
To put it simply I want the option selected in the dropdown to be set as a variable that I can use later on in my code. I am quite new to coding so I might be missing something really obvious, any help would be appreciated :)
I think for your use, the link provided by a_guest works best, but regarding your example, I think it's best to use the keyword textvariable of the label, i.e.
# note that this is the StringVar ICUS, not the combobox ICUSTOMER.
label_ICustVar = tk.Label( textvariable= ICus)
label_ICustVar.grid(row = 3, column = 3)
You can use <<ComboboxSelected>> event with the get() method.
def update_label(event):
label_ICustVar.configure(text=ICustomer.get())
ICustomer.bind("<<ComboboxSelected>>", update_label)
update_label method will be fired each time you select an item from combobox dropdown.
Using StringVar() is not necessary with this approach, so you can remove ICus.
I'm making a simple app just to practice python in which I want to write text as if it were Notepad. However, I can't make my entry bigger. I'm using tkinter for this. Does anybody know how to make the height of an entry bigger?
I tried something like this:
f = Frame()
f.pack()
e = Entry(f,textvariable=1,height=20)
e.pack()
I know this doesn't work because there isn't a property of "height". However, I see that there is a width property.
It sounds like you are looking for tkinter.Text, which allows you to adjust both the height and width of the widget. Below is a simple script to demonstrate:
from tkinter import Text, Tk
r = Tk()
r.geometry("400x400")
t = Text(r, height=20, width=40)
t.pack()
r.mainloop()
Another way would be to increase the internal padding by adding this in the pack method:
...
e = Entry(f,textvariable=1,height=20)
e.pack(ipady=3)
...
for instance. This worked for me for an 'Entry' and it also works with .grid()
Actually it's very easy. You don't need to set height in Entry(), but in place().
for example:
from tkinter import Entry, Tk
window = Tk()
t = Entry(window)
t.place(width=150,height=50)
window.mainloop()
from tkinter import *
root=Tk()
url = Label(root,text="Enter Url")
url.grid(row=0,padx=10,pady=10)
entry_url = Entry(root,width="50")
entry_url.grid(row=0,column=1,padx=5,pady=10,ipady=3)
root.geometry("600x300+150+150")
root.mainloop()
learn more follow this github
output image this is output of above code
You can also change it by changing the font size :
Entry(
root,
font=("default", 40 or 20 whatever )
)
To change an entry widget's size, you have to change it's font to a larger font.
Here is my code:
import tkinter as tk
large_font = ('Verdana',30)
small_font = ('Verdana',10)
root = tk.Tk()
entry1Var = tk.StringVar(value='Large Font!')
entry1 = tk.Entry(root,textvariable=entry1Var,font=large_font)
entry1.pack()
entry2Var = tk.StringVar(value='Small Font!')
entry2 = tk.Entry(root,textvariable=entry2Var,font=small_font)
entry2.pack()
root.mainloop()
You can change the height of the entry widget.
To do so you can write:
entry_box.place(height=40, width=100)
Change the value according to your needs!
IT WORKS !
By using the .place(width= , height= ) method, you can adjust the size of the entry. Another Method is to change the font of the text, but that limits your ability to change the font.
.place() method:
textbox.place(width= (Your desired width) ,height= (Your desired height))
Font Method:
textbox = Entry(root, font=("default", (Your font size))
Hope this helps!
I have a list of tkinter widgets that I want to change dynamically.
How to delete the widgets from the window?
You can call pack_forget to remove a widget (if you use pack to add it to the window).
Example:
from tkinter import *
root = Tk()
b = Button(root, text="Delete me", command=lambda: b.pack_forget())
b.pack()
root.mainloop()
If you use pack_forget, you can later show the widget again calling pack again. If you want to permanently delete it, call destroy on the widget (then you won't be able to re-add it).
If you use the grid method, you can use grid_forget or grid_remove to hide the widget.
One way you can do it, is to get the slaves list from the frame that needs to be cleared and destroy or "hide" them according to your needs. To get a clear frame you can do it like this:
from tkinter import *
root = Tk()
def clear():
list = root.grid_slaves()
for l in list:
l.destroy()
Label(root,text='Hello World!').grid(row=0)
Button(root,text='Clear',command=clear).grid(row=1)
root.mainloop()
You should call grid_slaves(), pack_slaves() or slaves() depending on the method you used to add the widget to the frame.
You simply use the destroy() method to delete the specified widgets like this:
lbl = tk.Label(....)
btn = tk.Button(....., command=lambda: lbl.destroy())
Using this you can completely destroy the specific widgets.
You say that you have a list of widgets to change dynamically. Do you want to reuse and reconfigure existing widgets, or create all new widgets and delete the old ones? It affects the answer.
If you want to reuse the existing widgets, just reconfigure them. Or, if you just want to hide some of them temporarily, use the corresponding "forget" method to hide them. If you mapped them with pack() calls, you would hide with pack_forget() (or just forget()) calls. Accordingly, grid_forget() to hide gridded widgets, and place_forget() for placed widgets.
If you do not intend to reuse the widgets, you can destroy them with a straight destroy() call, like widget.destroy(), to free up resources.
clear_btm=Button(master,text="Clear") #this button will delete the widgets
clear_btm["command"] = lambda one = button1, two = text1, three = entry1: clear(one,two,three) #pass the widgets
clear_btm.pack()
def clear(*widgets):
for widget in widgets:
widget.destroy() #finally we are deleting the widgets.
Today I learn some simple and good click event handling using tkinter gui library in python3, which I would like to share inside this thread.
from tkinter import *
cnt = 0
def MsgClick(event):
children = root.winfo_children()
for child in children:
# print("type of widget is : " + str(type(child)))
if str(type(child)) == "<class 'tkinter.Message'>":
# print("Here Message widget will destroy")
child.destroy()
return
def MsgMotion(event):
print("Mouse position: (%s %s)" % (event.x, event.y))
return
def ButtonClick(event):
global cnt, msg
cnt += 1
msg = Message(root, text="you just clicked the button..." + str(cnt) + "...time...")
msg.config(bg='lightgreen', font=('times', 24, 'italic'))
msg.bind("<Button-1>", MsgClick)
msg.bind("<Motion>", MsgMotion)
msg.pack()
#print(type(msg)) tkinter.Message
def ButtonDoubleClick(event):
import sys; sys.exit()
root = Tk()
root.title("My First GUI App in Python")
root.minsize(width=300, height=300)
root.maxsize(width=400, height=350)
button = Button(
root, text="Click Me!", width=40, height=3
)
button.pack()
button.bind("<Button-1>", ButtonClick)
button.bind("<Double-1>", ButtonDoubleClick)
root.mainloop()
Hope it will help someone...
You can use forget method on the widget
from tkinter import *
root = Tk()
b = Button(root, text="Delete me", command=b.forget)
b.pack()
b['command'] = b.forget
root.mainloop()
I found that when the widget is part of a function and the grid_remove is part of another function it does not remove the label. In this example...
def somefunction(self):
Label(self, text=" ").grid(row = 0, column = 0)
self.text_ent = Entry(self)
self.text_ent.grid(row = 1, column = 0)
def someotherfunction(self):
somefunction.text_ent.grid_remove()
...there is no valid way of removing the Label.
The only solution I could find is to give the label a name and make it global:
def somefunction(self):
global label
label = Label(self, text=" ")
label.grid(row = 0, column = 0)
self.text_ent = Entry(self)
self.text_ent.grid(row = 1, column = 0)
def someotherfunction(self):
global label
somefunction.text_ent.grid_remove()
label.grid_remove()
When I ran into this problem there was a class involved, one function being in the class and one not, so I'm not sure the global label lines are really needed in the above.