将变量传递到tkinter类窗口中

时间:2018-09-29 22:10:07

标签: python class variables tkinter multiprocessing

我想在tkinter中创建一个GUI,它不仅可以在按下按钮时执行命令,而且可以响应在单独线程中运行的较大脚本的状态。

我确实研究过,并试图找到有关消息传递的信息,并且我发现了使用多处理及其内置工具以及线程和排队的关于pickle模块的重要信息。我什至在here.中都深入研究了大卫·比兹利(David Beazley)关于并发性的课程,我只是无法正确理解任何一种方法的语法。

我已将代码分解为一个小的功能单元,该功能单元应启动一个tkinter小窗口,如下所示:

tkinter window

下面的代码具有启动我的tkinter GUI的“ launchGUI”功能,一个启动线程的“ myLoop”功能,并且稍后还会循环以驱动我的较大程序,现在它只是旋转眨眼变量。我的班级中也有一个blinkCheckCheck方法,该方法检查班级中blinking变量的状态。

我不知道我是否将消息接收器放在正确的位置。在下面的示例代码中,我只是试图将全局变量传递给类。我知道它正在进入该类,因为即使取消注释该方法会使窗口崩溃,也可以使用blinkCheck()方法起作用。但是,关闭该方法后,GUI中的标签将永远不变。我认为窗口崩溃是我最少的担心,这一定是因为我还有另一个while循环正在运行。

在Label中更改该数字的正确方法是什么?

这是我的示例代码:

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()

2 个答案:

答案 0 :(得分:0)

在您的描述中,您提到了有关涉及按钮的内容。在您提供的摘要中看不到该内容。但是使用按钮可以配置标签,即:

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)

通常,这是在活动线程中配置标签的最简单方法。

如果有人认为此答案可能不完全正确,请进行编辑,因为我是Stack Overflow的新手!

答案 1 :(得分:0)

首先,GUI必须在主线程中运行,并且不能被无限循环阻塞。请改用after。要进行通信,请使用线程中的一些适当对象,例如事件:

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()