将变量传递到tkinter类中

2024-10-05 19:24:11 发布

您现在位置:Python中文网/ 问答频道 /正文

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

我真的四处挖掘,试图找到一些关于消息传递的信息,我发现了一些关于pickle模块的有用信息,使用了多处理及其内置工具,还有线程和队列。我甚至深入研究了davidbeazley关于并发性的课程here.我只是无法正确理解这些方法中的任何一个。在

我已经将我的代码分解成一个小的功能单元,可以像这样启动一个小窗口:

tkinter window

下面的代码有一个“launchGUI”函数来启动我的tkinter GUI,一个启动线程的“myLoop”函数,稍后还会循环驱动我更大的程序,现在它只是旋转blink变量。我的类中还有一个blinkCheck方法,它检查类中blink变量的状态。在

我不知道我是否把我的信息接收器放在正确的地方。在下面的示例代码中,我只是尝试将一个全局变量传递到类中。我知道它正在进入类中,因为blinkCheck()方法可以工作,即使取消注释该方法会使窗口崩溃。但是,关闭该方法后,GUI中的标签永远不会更改。我想撞窗是我最不担心的,一定是因为我有另一个while循环在运行。在

要更改标签中的数字,正确的方法是什么?在

下面是我的示例代码:

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

Tags: 方法代码importselfmaster信息tkinterdef
2条回答

首先,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()

在你的描述中你提到了一些关于按钮的事情。我在你提供的片段中没有看到这一点。但通过按钮可以配置标签,即:

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)

按照惯例,这是在活动线程中配置标签的最简单方法。在

如果有人觉得这个答案可能不完全正确,请编辑它,因为我是新的堆栈溢出!在

相关问题 更多 >