Reputation: 3
I know how to change a label's color with a command attached to a button, but I want to do it programmatically, based on a variable's value.
If an error message is sent to the build_window
function, I want to display the error message on a label with a red background, and if a non-error message is sent, no message is to be displayed and no color changes are expected.
In my code, I call the function to build a tkinter window two times. The first time, I pass it a non-error message, the second time, an error message.
My code works for displaying the error message when expected, the problem is only with changing the background color of the error message label.
If I un-comment the l1.config(bg="red")
command shown, I get this error when passing an error message to build_window()
:
UnboundLocalError: local variable 'l1' referenced before assignment
on the l1.config(bg="red")
command.
If I move the entire if structure to just before mainloop()
, I get this error even when passing the non-error message:
UnboundLocalError: local variable 'error_message' referenced before assignment
on the l1=Label(root,text = error_message)
command.
If I add global l1
and global error_message
to build_window()
, the error I get is this:
tkinter.TclError: invalid command name ".!label"
I also tried just initially defining the label with bg="red"
, hoping that when I send a zero-length string, it would still be gray, but it displays a bit of red in the middle of the l1 label.
I've been writing simple python for a while, but I'm new to GUI apps and tkinter just confuses me every time I try something.
I've searched for a solution but could not find anything addressing changing a window without using a command attached to a button.
Any advice or clarification would be greatly appreciated!
from tkinter import Tk, IntVar, Label, mainloop, Button
def build_window(incoming_error_message) :
if incoming_error_message == "initial value" :
error_message = ""
else :
#l1.config(bg="red")
error_message = incoming_error_message
def quitHandler():
root.destroy()
root = Tk()
l1=Label(root,text = error_message)
l1.grid(row=0,column=0)
quitButton = Button(root, text="To end, click here",command=quitHandler)
quitButton.grid(row=1,column=0)
mainloop()
def call_build_window() :
build_window("initial value")
build_window("Error!")
call_build_window()
Upvotes: 0
Views: 1439
Reputation: 10238
One option is to place the label creation within the condition and reorder the surrounding code a little bit. I also replaced grid
by pack
and skipped keeping names for variables which are actually constants, all that changes were made to keep the code small:
from tkinter import Tk, Label, mainloop, Button
def build_window(error_message):
root = Tk()
if error_message == "initial value":
Label(root, text="").pack()
else:
Label(root, text=error_message, bg="red").pack()
def quitHandler():
root.destroy()
Button(root, text="To end, click here", command=quitHandler).pack()
mainloop()
def call_build_window():
build_window("initial value")
build_window("Error!")
call_build_window()
This of course is a small case study and shouldn't be used to build on it.
I think it should be reworked so that there is a maybe function that takes the indicator if the message is as a second argument with the text always being displayed. All that would be much easier in a more object-oriented approach. (Also remember that Tk()
is normally called only once and secondary top-level windows are created via Toplevel()
, see Python - Tkinter - invisible text in ttk.Entry in sub window or tkinter: Open a new window with a button prompt. )
By using tkinter.ttk
it's also possible to change the widget's style at runtime, see the answer to Changing ttk widget text color for an example.
Upvotes: 1