我想在 tkinter 中创建一个 GUI,它不仅在按下按钮时执行命令,而且响应在单独线程中运行的较大脚本的状态。
我真的四处挖掘并试图找到一些关于消息传递的信息,我找到了一些关于 pickle 模块的好信息,使用多处理及其内置工具以及线程和队列。 我甚至深入研究了David Beazley关于并发的课程。我只是无法在任何这些方法上获得正确的语法。
我已经将我的代码分解为一个小的功能单元,它应该启动一个小的tkinter窗口,如下所示:
特金特窗口
下面的代码有一个"launchGUI"函数,可以启动我的tkinter GUI,一个"myLoop"函数,它启动线程,稍后也会循环以驱动我更大的程序,现在它只是旋转blink变量。 我的类中还有一个 blinkCheck 方法,用于检查类中 blink 变量的状态。
我不知道我是否将消息接收器放在正确的位置。 在下面的示例代码中,我只是尝试将全局变量传递到类中。我知道它正在进入类,因为 blinkCheck(( 方法即使取消注释该方法会使窗口崩溃,该方法也可以工作。 但是,关闭该方法后,GUI 中的标签永远不会更改。 我认为窗户崩溃是我最不担心的,这一定是因为我还有另一个循环运行。
让标签中的数字更改的正确方法是什么?
这是我的示例代码:
import tkinter as tk
from tkinter import Frame, Label
import time
import threading
blink = 0
class MyClass(tk.Frame):
def __init__(self, master):
self.master = master
super().__init__(self.master)
global blink
self.label = Label(master, text=blink)
self.label.pack()
#self.blinkCheck()
def blinkCheck(self):
global blink
while True:
print("blink in blinkCheck method is = {}".format(blink))
time.sleep(2.5)
def launchGUI():
root = tk.Tk()
root.title("My Blinker")
app1 = MyClass(root)
app1.mainloop()
def myLoop():
global blink
t1=threading.Thread(target=launchGUI)
t1.daemon = True
t1.start()
print("blink in blinker function is {}".format(blink))
while True:
if blink == 0:
blink = 1
else:
if blink == 1:
blink = 0
time.sleep(2.5)
if __name__=="__main__":
myLoop()
在您的描述中,您提到了有关涉及按钮的内容。我在您提供的片段中没有看到这一点。但是使用按钮可以配置标签,即:
from tkinter import Label, Button
blink = 0
class MyClass(tk.Frame):
def __init__(self, master):
self.master = master
super().__init__(self.master)
global blink
self.label = Label(master, text=blink)
self.button = Button(master, text="Button", command=lambda: foo(self.label))
self.label.pack()
self.button.pack()
#self.blinkCheck()
def blinkCheck(self):
global blink
while True:
print("blink in blinkCheck method is = {}".format(blink))
time.sleep(2.5)
def foo(self, label):
label.config(text=blink)
传统上,这是在活动线程中配置标签的最简单方法。
如果有人觉得这个答案可能不完全正确,请编辑它,因为我是堆栈溢出的新手!
首先,GUI 必须在主线程中运行,并且不得被无限循环阻塞。请改用after
。要进行通信,请使用线程中的一些适当的对象,例如 Event:
import tkinter as tk
import time
import threading
class MyClass(tk.Frame):
def __init__(self, master, event):
super().__init__(master)
self.master = master
self.event = event
self.label = tk.Label(master, text='')
self.label.pack()
self.after(100, self.blink_check)
def blink_check(self):
self.label['text'] = self.event.is_set()
self.after(100, self.blink_check)
def blink(event):
while True:
event.set()
time.sleep(2.5)
event.clear()
time.sleep(2.5)
def main():
root = tk.Tk()
root.title("My Blinker")
event = threading.Event()
t = threading.Thread(target=blink, args=(event,))
t.daemon = True
t.start()
frame = MyClass(root, event)
root.mainloop()
if __name__=="__main__":
main()