1

我正在尝试从主函数操作线程中的一些数据。我面临的问题是修改一些变量,这些变量是在线程上运行的函数的一部分。

所以我试图在一个线程中运行一个基于 Tkinter 的 GUI 循环,以确保它始终在运行。并且想在main函数执行中修改一些状态对应的标签。我面临一个问题,它无法在主循环中找到标签变量,因为它是在线程上运行的函数的一部分。

下面是该方法的简化伪代码。请建议这是否是上述任务的正确方法,或者是否有更好和有效的方法。

import threading

def thread_func():
    i = 0
    while True:
        print('i from thread: ', i)

if __name__ == '__main__':
    t = threading.Thread(target=thread_func)
    t.start()
    
    while True:
        i += 1

实际缩小的简化代码

import threading
import tkinter as tk

def gui():
    window = tk.Tk()
    label = tk.Label(text='On')
    label.pack()
    window.mainloop()

if __name__ == '__main__':
    t = threading.Thread(target=gui)
    t.start()
    
    while True:
        label['text'] = 'Active'

错误:

Traceback (most recent call last):
  File "test.py", line 17, in <module>
    label['text'] = 'Active'
NameError: name 'label' is not defined

有没有更好的方法来保持 tkinter gui 始终打开并在循环中执行某些任务?

4

2 回答 2

1

当您在那里编写标签代码时,您将收到错误,因为当程序启动时它从创建线程开始,该线程只会在 tkinter 窗口关闭并且与之前的thread_fuc代码相同时结束。你在 tkinter 窗口关闭后编写了标签代码。

上述问题将通过这样做来解决:

import threading

def thread_func():
    while True:
        print('i from thread: ', i)

def tt():
    global i
    while True:
        i += 1

if __name__ == '__main__':
    i=0
    t = threading.Thread(target=thread_func)
    t.start()
    yt = threading.Thread(target=tt)
    yt.start()

使i全局和运行 2 功能并行。我们必须这样做,global因为我们不能将一个函数的变量用于另一个函数。此外,我们在 2 个线程中运行 2 个函数。

对于tkinter@TheLizzard 建议的文件,如果您想不断更改内容/想要使用循环,则可以使用.afterinsted 的使用线程。 这是如何实现它的基本示例:tkinter

import random
import tkinter as tk

app = tk.Tk()
app.geometry("200x220")

label = tk.Label(app, text="0")
label.pack()

def change(b=0):
    if b < 30:
        a = random.randrange(1, 7, 1)
        label.config(text=a)
        app.after(100, change, b+1)

b1 = tk.Button(app, text="Get New Number", command=change)
b1.pack()

app.mainloop()

有关它的更多说明,您可以访问此处

于 2021-07-29T19:10:49.557 回答
1

使用类和线程:

import tkinter


class Test(tkinter.Label):

    x = False

    def __init__(self):
        super().__init__()
        self.pack()
        self['text'] = 'On'

    def gui(self):
        if not self.x:
            self['text'] = 'Active'
            self.mainloop()
        else:
            self.mainloop()


if __name__ == '__main__':
    label = Test()
    while isinstance(label, Test):
        t = threading.Thread(target=label.gui())
        t.start()

于 2021-07-29T19:49:59.210 回答