如何使用 window.mainloop 之外的回调函数更改 Tkinter 中的标签文本
how to change label text in Tkinter with callback function out of window.mainloop
im 触发回调函数 读取编码器输出
使用 GPIO.add_event_detect
所以 global counter
具有当前值,但我不能像使用 listbox.insert(END,counter)
那样将它传递给 tkinter
import RPi.GPIO as GPIO
from tkinter import ttk
import tkinter as tk
counter = 0
# GPIO Pins #
A = 17
B = 27
#-----------#
# GPIO settings
GPIO.setwarnings(True)
GPIO.setmode(GPIO.BCM)
#
GPIO.setup(A, GPIO.IN)
GPIO.setup(B, GPIO.IN)
def Enc(A):
global counter
sleep(0.002)
input_A = GPIO.input(A)
input_B = GPIO.input(B)
if (input_A == 1) and (input_B == 0):
counter += 1
print (counter)
#listbox.insert(END,counter)
elif (input_A == 1) and (input_B == 1):
counter -= 1
print (counter)
#listbox.insert(END,counter)
else:
return
# GPIO output detection
GPIO.add_event_detect(A, GPIO.RISING, callback=Enc, bouncetime=10)
# window settings
window = tk.Tk()
window.title("encoder_value")
# string value?
window.Enc_counter_str = tk.StringVar(value=counter)
# label
tk.Label(window, text='Enc:',fg = "medium violet red", bg = "light grey", font = "Helvetica 16 bold italic").grid(column=0, row=0, **padding)
# output label
window.Enc_label = tk.Label(window)
window.Enc_label.grid(column=0, row=2, columnspan=1, **padding)
window.Enc_label.config(text=window.Enc_counter_str.get(),fg = "medium violet red", bg = "light grey", font = "Helvetica 16 bold italic")
# tk window loop
window.mainloop()
只需在 Enc
函数中使用 window.Enc_label["text"] = str(counter)
。
因此,根据我在阅读您的问题后的理解,您似乎在每次计数器值更改时尝试更新 window.Enc_label 的值。
这里的问题是这一行 -:
window.Enc_counter_str = tk.StringVar(value=counter)
此处,当您将字符串 var 的值设置为计数器时,您所做的只是分配计数器的“那个时间”值(假设执行此行时计数器为 1,因此字符串变量的值被分配为 1 而不是对实际变量的引用。)
但它有效,因为您确实希望初始值也相同。
另一个问题是您没有更新字符串 var 的值,因为您假设字符串 var 存储了计数器的引用,但它没有。
所以每次修改计数器的值时都可以这样做-:
def Enc(A):
global counter
sleep(0.002)
input_A = GPIO.input(A)
input_B = GPIO.input(B)
if (input_A == 1) and (input_B == 0):
counter += 1
print (counter)
elif (input_A == 1) and (input_B == 1):
counter -= 1
print (counter)
else:
return
window.Enc_counter_str.set(counter)
现在您还希望 Label 对象立即知道字符串变量是从中获取值的位置,因此它会定期检查它是否有更新,您可以像这样传递 textvariable 参数来实现-:
window.Enc_label = tk.Label(window, textvariable = window.Enc_counter_str)
还有另一种方法,虽然不是很简洁,但也是一个可行的解决方案,就是你 运行 每次更新计数器时都使用这一行 -:
window.Enc_label.config(text=window.Enc_counter_str.get(),fg = "medium violet red", bg = "light grey", font = "Helvetica 16 bold italic")
现在这一行目前您只是 运行正在初始化 Label 对象,因此文本不会更新。
但是使用我们的第一种方法,这一行可以缩短为 -:
window.Enc_label.config(fg = "medium violet red", bg = "light grey", font = "Helvetica 16 bold italic")
现在还要确保将标签声明放在函数之前,以便 python 已经知道您引用的字符串变量。
最终代码变为-:
import RPi.GPIO as GPIO
from tkinter import ttk
import tkinter as tk
counter = 0
# GPIO Pins #
A = 17
B = 27
#-----------#
# GPIO settings
GPIO.setwarnings(True)
GPIO.setmode(GPIO.BCM)
#
GPIO.setup(A, GPIO.IN)
GPIO.setup(B, GPIO.IN)
# window settings
window = tk.Tk()
window.title("encoder_value")
# string value?
window.Enc_counter_str = tk.StringVar(value=counter)
# label
tk.Label(window, text='Enc:',fg = "medium violet red", bg = "light grey", font = "Helvetica 16 bold italic").grid(column=0, row=0, **padding)
# output label
window.Enc_label = tk.Label(window, textvariable = window.Enc_counter_str) # CHANGE 1
window.Enc_label.grid(column=0, row=2, columnspan=1, **padding)
window.Enc_label.config(fg = "medium violet red", bg = "light grey", font = "Helvetica 16 bold italic") # CHANGE 2
def Enc(A):
global counter
sleep(0.002)
input_A = GPIO.input(A)
input_B = GPIO.input(B)
if (input_A == 1) and (input_B == 0):
counter += 1
print (counter)
elif (input_A == 1) and (input_B == 1):
counter -= 1
print (counter)
else:
return
window.Enc_counter_str.set(counter) # CHANGE 3
# GPIO output detection
GPIO.add_event_detect(A, GPIO.RISING, callback=Enc, bouncetime=10)
# tk window loop
window.mainloop()
im 触发回调函数 读取编码器输出
使用 GPIO.add_event_detect
所以 global counter
具有当前值,但我不能像使用 listbox.insert(END,counter)
import RPi.GPIO as GPIO
from tkinter import ttk
import tkinter as tk
counter = 0
# GPIO Pins #
A = 17
B = 27
#-----------#
# GPIO settings
GPIO.setwarnings(True)
GPIO.setmode(GPIO.BCM)
#
GPIO.setup(A, GPIO.IN)
GPIO.setup(B, GPIO.IN)
def Enc(A):
global counter
sleep(0.002)
input_A = GPIO.input(A)
input_B = GPIO.input(B)
if (input_A == 1) and (input_B == 0):
counter += 1
print (counter)
#listbox.insert(END,counter)
elif (input_A == 1) and (input_B == 1):
counter -= 1
print (counter)
#listbox.insert(END,counter)
else:
return
# GPIO output detection
GPIO.add_event_detect(A, GPIO.RISING, callback=Enc, bouncetime=10)
# window settings
window = tk.Tk()
window.title("encoder_value")
# string value?
window.Enc_counter_str = tk.StringVar(value=counter)
# label
tk.Label(window, text='Enc:',fg = "medium violet red", bg = "light grey", font = "Helvetica 16 bold italic").grid(column=0, row=0, **padding)
# output label
window.Enc_label = tk.Label(window)
window.Enc_label.grid(column=0, row=2, columnspan=1, **padding)
window.Enc_label.config(text=window.Enc_counter_str.get(),fg = "medium violet red", bg = "light grey", font = "Helvetica 16 bold italic")
# tk window loop
window.mainloop()
只需在 Enc
函数中使用 window.Enc_label["text"] = str(counter)
。
因此,根据我在阅读您的问题后的理解,您似乎在每次计数器值更改时尝试更新 window.Enc_label 的值。
这里的问题是这一行 -:
window.Enc_counter_str = tk.StringVar(value=counter)
此处,当您将字符串 var 的值设置为计数器时,您所做的只是分配计数器的“那个时间”值(假设执行此行时计数器为 1,因此字符串变量的值被分配为 1 而不是对实际变量的引用。)
但它有效,因为您确实希望初始值也相同。 另一个问题是您没有更新字符串 var 的值,因为您假设字符串 var 存储了计数器的引用,但它没有。
所以每次修改计数器的值时都可以这样做-:
def Enc(A):
global counter
sleep(0.002)
input_A = GPIO.input(A)
input_B = GPIO.input(B)
if (input_A == 1) and (input_B == 0):
counter += 1
print (counter)
elif (input_A == 1) and (input_B == 1):
counter -= 1
print (counter)
else:
return
window.Enc_counter_str.set(counter)
现在您还希望 Label 对象立即知道字符串变量是从中获取值的位置,因此它会定期检查它是否有更新,您可以像这样传递 textvariable 参数来实现-:
window.Enc_label = tk.Label(window, textvariable = window.Enc_counter_str)
还有另一种方法,虽然不是很简洁,但也是一个可行的解决方案,就是你 运行 每次更新计数器时都使用这一行 -:
window.Enc_label.config(text=window.Enc_counter_str.get(),fg = "medium violet red", bg = "light grey", font = "Helvetica 16 bold italic")
现在这一行目前您只是 运行正在初始化 Label 对象,因此文本不会更新。
但是使用我们的第一种方法,这一行可以缩短为 -:
window.Enc_label.config(fg = "medium violet red", bg = "light grey", font = "Helvetica 16 bold italic")
现在还要确保将标签声明放在函数之前,以便 python 已经知道您引用的字符串变量。
最终代码变为-:
import RPi.GPIO as GPIO
from tkinter import ttk
import tkinter as tk
counter = 0
# GPIO Pins #
A = 17
B = 27
#-----------#
# GPIO settings
GPIO.setwarnings(True)
GPIO.setmode(GPIO.BCM)
#
GPIO.setup(A, GPIO.IN)
GPIO.setup(B, GPIO.IN)
# window settings
window = tk.Tk()
window.title("encoder_value")
# string value?
window.Enc_counter_str = tk.StringVar(value=counter)
# label
tk.Label(window, text='Enc:',fg = "medium violet red", bg = "light grey", font = "Helvetica 16 bold italic").grid(column=0, row=0, **padding)
# output label
window.Enc_label = tk.Label(window, textvariable = window.Enc_counter_str) # CHANGE 1
window.Enc_label.grid(column=0, row=2, columnspan=1, **padding)
window.Enc_label.config(fg = "medium violet red", bg = "light grey", font = "Helvetica 16 bold italic") # CHANGE 2
def Enc(A):
global counter
sleep(0.002)
input_A = GPIO.input(A)
input_B = GPIO.input(B)
if (input_A == 1) and (input_B == 0):
counter += 1
print (counter)
elif (input_A == 1) and (input_B == 1):
counter -= 1
print (counter)
else:
return
window.Enc_counter_str.set(counter) # CHANGE 3
# GPIO output detection
GPIO.add_event_detect(A, GPIO.RISING, callback=Enc, bouncetime=10)
# tk window loop
window.mainloop()