I am building a gui to control Rasp Pi 4. I have a main script pin_gui1.py.
I have all of my control functions in pin_control_stub1.py, which I am importing.
Can successfully run those functions on button presses.
But error comes when the function tries to change text property of a Label widget in the root script.
Problem: This works fine of I define the function in main script, but get NameError if in imported script. You can see the functions run successfully, and I can even pass them values from the main script, and print to console. But get error 'lbl_command' not defined when I try to change that label's text.
To see this error, click the "All On" or "All Off" buttons.
My guess is that the functions in imported scriot are compiled on import, so other widgets in main script are not defined yet. But I can't figure out how to delay this (if that is the problem). Appreciate any suggestions.
Imported script is only a stub right now: the final will have full board control commands, so the desired result is to be able to show the commands sent to the board in the label at the bottom of the gui named 'lbl_command'.
pin_gui1.py:
#GUI to control Raspberry Pi 4
import tkinter as tk
import pin_control_stub1 as p
# If i define functions here, they can alter text in lbl_command
def randflash():
print("Random Flash 5 sec")
lbl_command["text"] = "Random Flash 5 sec"
m = tk.Tk()
m.title("CONTROL GUI")
m.geometry('500x400')
# This is outside other frames
banner = tk.Label(text="Control Panel for pin_control", fg='cyan', bg='black')
banner.pack()
frame1 = tk.Frame(master=m, width=300, height=200, bg='#888')
frame1.pack(fill='both', expand=True)
btn1 = tk.Button(frame1, width=10, text='Random Flash 5 sec', command=randflash) #command=lambda: p.randflash(5)
btn2 = tk.Button(frame1, width=10, text='All On', command=p.all_on, fg='green')
btn3 = tk.Button(frame1, width=10, text='All Off', command=p.all_off, fg='red')
btn1.pack(side='left',padx=5,ipadx=20,ipady=10)
btn2.pack(side='left',padx=5,ipadx=20,ipady=10)
btn3.pack(side='left',padx=5,ipadx=20,ipady=10)
# 2nd frame holds pin/color buttons
frame2 = tk.Frame(master=m, width=300, height=200, relief=tk.SUNKEN, bg='#ccc')
frame2.pack(expand=True, fill="both")
for i in range(len(p.pins)):
txt = 'Pin ' + str(p.pins[i]) + ': ' + p.colors[i]
tk.Button(frame2, width=10,text=txt, command=lambda i=i: p.do_pin(p.pins[i])).grid(pady=2)
frame3 = tk.Frame(master=m, width=300, height=100, bg='#888')
frame3.pack(expand=True, fill='both')
lbl_command = tk.Label(frame3, text=' -- commands --', relief=tk.SUNKEN, bg='#ccc')
lbl_command.pack(ipadx=30)
m.mainloop()
pin_control_stub1.py:
# This stub exists only to test pin_gui1.py on laptop
# The real pin_control.py runs only on Raspberry Pi 4
pins = [12,13,16,21,22,23,24,25]
colors = ['red','green','blue','red','green','blue','yellow','yellow']
# def randflash():
# print("Random Flash 5 sec")
# lbl_command["text"] = "Random Flash 5 sec"
def all_on():
print("Turns all on")
lbl_command["text"] = "All ON"
# NOTE: This causes NameError: name 'lbl_command' is not defined.
# Works only if I move this function to pin_gui.py
def all_off():
print("Turns all off")
p.lbl_command["text"] = "All OFF"
# NOTE: This causes NameError: name 'p' is not defined.
# Works only if I move this function to pin_gui.py
def do_pin(x):
print("turns on pin#" + str(x))