Python Tkinter Label not updating in new window - python

So I've got a function that opens a new window. In this window I am trying to update a Label, when I use textvariable it doesn't update and the label always stays blank. With just text, the label will show the text.
My textvariable's work in my main window but not in this one and I have no idea why.
def Manage():
PropsP1 = Tk()
area = Canvas(PropsP1, width = 920, height = 970)
area.pack()
MedCR = StringVar()
MedO = 1
count = 1
MedR = 4
if MedO == count:
MedCRLabel = Label(PropsP1, textvariable=MedCR, bg = "White")
MedCRLabel.place(x = 15, y = 65)
MedCR.set("Current Rent: "+str(MedR))
This is the function, I've tried making multiple Labels and none display anything with textvariable. I can see a white square for the label so I know it is showing up but there is no text.

The problem is that you are creating a new instance of Tk. A tkinter application should only ever create a single instance of Tk, and call mainloop exactly once. To create a popup window, create an instance of Toplevel.

Related

Create Tkinter buttons in a loop that reference each other

I'm trying to create a series of tkinter buttons with a loop that are .grid'd to their own respective frames. I want every button to have a function that .tkraises the next frame in the list of frames that I create. Any idea how? Here's what I've got. The buttons/ frames are created I think but the .tkraise function doesn't work. Thanks
from tkinter import *
from PIL import ImageTk, Image
## Define root and geometry
root = Tk()
root.geometry('200x200')
# Define Frames
winlist = list()
winlist = Frame(root, bg='red'), Frame(root, bg='green'), Frame(root, bg='blue')
# Configure Rows
root.grid_rowconfigure(0, weight = 1)
root.grid_columnconfigure(0, weight = 1)
# Place Frames
for window in winlist:
window.grid(row=0, column = 0, sticky = 'news')
# Raises first window 'To the top'
winlist[0].tkraise()
# Function to raise 'window' to the top
def raise_frame(window):
window.tkraise()
d = {}
count = 0
for x in range(0, 3):
d["label{0}".format(x)] = Label(winlist[x], text = "label{0}".format(x))
if count <=1:
try:
d["button{0}".format(x)] = Button(winlist[x], text = "button{0}".format(x), command = raise_frame(winlist[x+1]))
d["button{0}".format(x)].pack(side=TOP)
except:
pass
else:
d["label{0}".format(x)].pack(side=TOP)
count += 1
root.mainloop()
The issue is on the command option of the line:
d["button{0}".format(x)] = Button(winlist[x], text = "button{0}".format(x), command = raise_frame(winlist[x+1]))
It will execute raise_frame(winlist[x+1]) immediately and then assign the result (which is None) to command option. Therefore, clicking the button later does nothing.
You need to use lambda instead:
d["button{0}".format(x)] = Button(winlist[x], text="button{0}".format(x),
command=lambda x=x: raise_frame(winlist[x+1]))
I answered my own question. instead of using frames I went back to creating Tk() objects. I made a loop that runs a function that creates Tk() objects and passed in a variable that carried the count of my loop. I used that count to change information on each Tk() object and instead made the 'command =' of each button include a Tk().destroy function. This creates all the windows I wanted all at once and I can perform an action and exit the window. It's progress. Thanks,
Tim,

How do I make a LabelFrame's frame not visible? (Tkinter)

My code is the following:
import tkinter as tk
from tkinter import ttk
window = tk.Tk()
window.title('None')
label = ttk.LabelFrame(window, text = 'What I want to delete')
label.grid(column = 0, row = 0, padx = 5, pady = 5)
text = ttk.Label(label, text = 'Hello World')
text.grid(column = 0, row = 0)
window.mainloop()
with frame
Now what surprises me is that when I do the following changes:
import tkinter as tk
from tkinter import ttk
window = tk.Tk()
window.title('None')
label = ttk.LabelFrame(window, text = 'What I want to delete').grid(column = 0, row = 0, padx = 5, pady=5)
text = ttk.Label(label, text = 'Hello World').grid(column = 0, row = 0)
window.mainloop()
The label's frame does not appear. Only the text. As shown below:
without frame
Which means that the LabelFrame is existent, but not shown because there's no error. I think.
In summary, that's the way I "solved it". So, my question is, Is there a fuction that makes It possible not to show the frame in a LabelFrame?
ttk.LabelFrames are only visible if there is something inside it or if they have a fixed size. In the fisrt example you gave the ttl.Label widget with text='Hello Word' is clearly inside the LabelFrame since you passed it as its parent. But in the second example it's not. You may think it is because you also defined label as the ttk.Label parent but if you do print(label) you will see it will print None and, in tkinter, if you pass None as a widget master it will understand that the master is the root Tk() widget.
So, why this happens? The difference between the two examples is that in the first label=ttk.LabelFrame() which is a LabelFrame object (an instance of the LabelFrame class), while in the second label=ttk.LabelFrame().grid() which is the output of the grid method, and since the grid method does not return anything label is equal to None. In conclusion what you are doing is putting the LabelFrame with anything inside and then the second Label, both in the same position of the master window and this is why you can't see the LabelFrame.
Ok, then how to make the LabelFrame invisible? The best option is not using ttk.LabelFrame but tk.LabelFrame because now you can disappear with the border using label.configure({"relief":"flat", "text":""}). Of course this will look like the frame is not there, but everything inside the frame will still be visible. If you want to disappear with things inside the label you can use either label.destroy() (you will not be able to recover the label) or label.grid_forget() (which will only 'ungrid' the label).

Python tkinter updating canvas label outside the main function

I am trying to update the canvas label outside the function that canvas was created.
def Application_GUI():
global Scanned_serial
global label1
global label2
global window
global label_gaminys
global canvas_tk
window = Tk() # create a GUI window
window.geometry("1920x1080") # set the configuration of GUI window
canvas_tk = Canvas(window,bg='ivory2',width=1920,height=1080)
canvas_tk.pack()
label1=Label(canvas_tk,text = "SKENUOKITE BARKODA(GUID) ARBA DAIKTO RIVILINI KODA:",bg='ivory2')
entry = Entry(canvas_tk) # entry = guid
canvas_tk.create_window(960,50,window=label1)
canvas_tk.create_window(960,100,window=entry)
var = IntVar()
button = Button(canvas_tk,text="Testi operacija",width = 30,height=2,command = lambda: var.set(1))
button2 = Button(canvas_tk,text="RESTART DEVICES",width = 30,height=2,command = lambda:restart_devices(myConnection))
ota_button = Button(canvas_tk, text="OTA", width=30, height=1, command=OTA_gui)
canvas_tk.create_window(960,150,window=button)
canvas_tk.create_window(960,200,window=button2)
canvas_tk.create_window(960,250,window=ota_button)
# ********************* IMPORTANT PART *************************
label_gaminys=Label(canvas_tk,text = "GAMINIO KODAS:",bg='ivory2')
canvas_tk.create_window(960,450,window=label_gaminys)
# ***************************************************************
print("waiting...")
button.wait_variable(var)
result = entry.get()
print("result=",result)
Scanned_serial = entry.get()
label2=Label(window,text = "Vykdoma operacija:")
label2.pack()
window.update()
In the function above, I am creating my user interface using a canvas. The important line of code is there:
label_gaminys=Label(canvas_tk,text = "GAMINIO KODAS:",bg='ivory2')
canvas_tk.create_window(960,450,window=label_gaminys)
I have created a window for a text at location 960,450.
I want to update this label outside this GUI function during a operation .
def Full_operation():
#Destroy previous window
window.destroy()
#create a new GUI window
Application_GUI()
global canvas_tk
operacijos_kodas=Scanning_operation(myConnection,Scanned_serial)
elif(operacijos_kodas == 1):
insertData_komplektacija(myConnection,"fmb110bbv801.csv");
update_current_operation(myConnection);
#label2.config(text = "Take items from the box:")#update the label2
label_gaminys=Label(canvas_tk,text = "Gamninio kodas=%s"%(Scanned_serial),bg='ivory2')
canvas_tk.create_window(960,450,window=label_gaminys)
picking_operation(myConnection,label2);
The function above describes the operatio. I want to modify the label inside this function. I have described my canvas_tk as global and initialise in this function so I can access and modify it. I have managed to update the label by creating a new window as following:
label_gaminys=Label(canvas_tk,text = "Gamninio kodas=%s"%(Scanned_serial),bg='ivory2')
canvas_tk.create_window(960,450,window=label_gaminys)
picking_operation(myConnection,label2);
But that does not seem like a correct way to do that since I am not actually "updating" the label, instead I am creating a new window and assigning it to a new label.
Could someone give me some general advice on how to do that properly?
You can just create a function that does this:
label_gaminys["text'] = "" #Insert the text you want into it and then the text changes
and then you can modify it whilst being in the same window. On another note, do notice that your Full_operation has an elif in it without an if first (just notifying you, because if there is no if before it it will cause an error).

tkinter grid manager behaviour

So i want to build an assistant off sorts which will do auto backs ups etc and instead of using .place i would like a proper grid to place widgets.
I cannot find a good example of the grid manager.
self.parent = tk.Frame(window, bg = BLACK)
username_label = ttk.Label(self.parent, text = "Username")
password_label = ttk.Label(self.parent, text = "Password")
self.parent.grid(column = 0, row = 0)
username_label.grid(column = 1, row = 1)
password_label.grid(column = 2, row = 2)
self.parent.grid_columnconfigure(0, weight = 1)
I want...
Button
Button
Label Entry Button
Label Entry Button
Button
I don't understand how i can position them like this as i want a blank space above the labels. so far grid has only let me place things next to each other.
Honestly, any websites or code examples would be greatly appreciated
So, if you want blank space above the label, you can either set pady as an argument to the grid method or simply put them in the corresponding row. Consider the following example:
import tkinter as tk
root=tk.Tk()
for i in range(6):
tk.Button(root,text='Button %d'%i).grid(row=i,column=1)
tk.Label(root,text='Label 0').grid(row=2,column=0,pady=20)
tk.Label(root,text='Label 1').grid(row=3,column=0)
root.mainloop()
Notice the effect of the pady argument. Also, if you only want a blank line above the Label, you can try to put a blank Label in the row above. E.g.:
import tkinter as tk
root=tk.Tk()
for i in range(6):
tk.Button(root,text='Button %d'%i).grid(row=i,column=1)
tk.Label(root,text='Label 0').grid(row=2,column=0,pady=20)
tk.Label(root,text='Label 1').grid(row=3,column=0)
tk.Label(root,text='').grid(row=6)
tk.Label(root,text='This is a Label with a blank row above').grid(row=7,columnspan=2)
root.mainloop()
You can refer to effbot for more information, which is the blog of tkinter's developer.

When using python Tkinter, how can I stop two entry box's in the same class showing the same input text?

I am having this issue with Python Tkinter. I am trying to make a user interface form screen which requires the user to enter values into entry box's displayed on screen. I have set it so the two Entry Box's are in the same class (that class being the interface screen). The problem is that while I type into one of the box's, the text which I type not only displays in the box in which I am typing into, but also in the other box.
Below is the code in question.
class GenericSkeleton: # The template for all the screens in the program
def __init__(self):
self.GenericGui = Tk()
self.GenericGui.title('Radial Arc Calculator')
self.GenericGui.geometry('360x540')
self.GenericGui.resizable(width = FALSE, height = FALSE)
Label(self.GenericGui,text = 'Radial Arc Calculator',font = ('Ariel',18)).place(x=65,y=35)
def destroy(self):
self.GenericGui.destroy()
class InputScreen(GenericSkeleton):
def __init__(self):
GenericSkeleton.__init__(self)
Button(self.GenericGui,text = 'CALCULATE',height = 1, width = 25, command = calculate, font = ('TkDefaultFont',14)).place(x=37,y=400)
Button(self.GenericGui,text = 'CLOSE',height = 1, width = 11, command = close, font = ('TkDefaultFont',14)).place(x=37, y=450)
Button(self.GenericGui,text = 'HELP', height = 1, width = 11, command = DisplayHelp, font = ('TkDefaultFont',14)).place(x=190, y=450)
Label(self.GenericGui,text = 'Enter Radius (mm):', font = ('TkDefaultFont',14)).place(x=37, y=180)
Label(self.GenericGui,text = 'Enter point distance (mm):', font = ('TkDefaultFont',14)).place(x=37, y=250)
Entry(self.GenericGui,textvariable = Radius, width = 10, font = ('TkDefaultFont',14)).place(x=210, y=180)
Entry(self.GenericGui,textvariable = Distance, width = 5, font = ('TkDefaultFont',14)).place(x=265, y=250)
run = InputScreen()
The entry box's are at the bottom of the code, I hope its enough/not too much to solve the problem.
The problem is that they both share the same textvariable (you use different variable names, but they have the same value which makes them the same in the eyes of tkinter). My advice is to not use the textvariable attribute. You don't need it.
However, if you remove the use of textvariable then you need to separate your widget creation from widget layout so that you can keep a reference to the widget. Then you can use the get method on the widget (rather than on the variable) to get the value:
self.entry1 = Entry(...)
self.entry2 = Entry(...)
self.entry1.place(...)
self.entry2.place(...)
Later, you can get the values like this:
radius = int(self.entry1.get())
distance = int(self.entry2.get())
If you do need the textvariable (usually only if you're using the trace feature of a tkinter variable), you must use a tkinter variable (StringVar, IntVar, etc) rather than a regular variable.

Categories

Resources