Функция в импортированном модуле не может обращаться к метке в модуле root - PullRequest
0 голосов
/ 12 апреля 2020

Я создаю gui для управления R asp Pi 4. У меня есть главный скрипт pin_gui1.py.
У меня есть все мои управляющие функции в pin_control_stub1.py, которые я импортирую. Может успешно запускать эти функции при нажатии кнопок. Но ошибка возникает, когда функция пытается изменить текстовое свойство виджета Label в сценарии root.

Проблема: Это нормально работает, если я определил функцию в основном сценарии, но получаю NameError, если в импортированном сценарии. Вы можете видеть, что функции выполняются успешно, и я даже могу передать их значения из основного сценария и распечатать на консоль. Но при попытке изменить текст этой метки ошибка «lbl_command» не определена.
Чтобы увидеть эту ошибку, нажмите кнопки «Все вкл.» Или «Все выкл.».

Я предполагаю, что функции в импортируемом scriot компилируются при импорте, поэтому другие виджеты в основном скрипте еще не определены. Но я не могу понять, как отложить это (если это проблема). Примите во внимание любые предложения.

Импортированный скрипт является всего лишь заглушкой прямо сейчас: финал будет иметь полные команды управления доской, поэтому желаемый результат должен быть в состоянии показать команды, отправленные на доску, на ярлыке внизу. gui с именем '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))

1 Ответ

0 голосов
/ 21 апреля 2020

Для тех, кто заинтересован, вот как я решил эту проблему. Я наконец нашел подсказку, которая мне нужна здесь

В основной скрипт (pin_gui1.py) включите эту строку, но она должна быть в конце скрипта:

p.addglobals(globals())

Затем в импортированном скрипте (pin_control_stub1.py) включите эту строку:

addglobals = lambda x: globals().update(x)

Намного лучшее объяснение того, как это работает в приведенной выше ссылке, но это решило мою проблему и работает отлично .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...