【问题标题】:Why doesn't wait_variable work in my code as expected?为什么 wait_variable 在我的代码中没有按预期工作?
【发布时间】:2019-07-02 12:14:23
【问题描述】:

我试图让 tkinter 程序在函数执行过程中等待,等到变量在单独的线程中发生更改,然后继续。提供的代码不是实际任务,这是我尝试理解wait_variable 并使其至少在某些方面起作用。

任务本身实际上是这样的:我试图让我的代码等到 Windows 服务状态发生更改然后继续。所以我使用了this 代码,我需要等到状态发生变化。

这是我在尝试使其工作时编写的代码:

import time
import tkinter as tk

from threading import Thread
from tkinter import messagebox


def test():
    my_var = tk.IntVar()
    my_var.set(1)

    label_2 = tk.Label(textvariable=my_var)
    label_2.pack()

    def wait_for_var():
        nonlocal my_var
        for i in range(5):
            label.config(text='iteration {}'.format(i))
            time.sleep(1)
            my_var.set(1)
        my_var.set(2)

    Thread(target=wait_for_var).start()
    while my_var.get() != 2:
        root.wait_variable('my_var')
        messagebox.showinfo('aha!', 'my_var changed!')
    messagebox.showinfo('done!', 'done!')


root = tk.Tk()
root.geometry('800x600')

text = 'init'

label = tk.Label(text='init')
label.pack()

btn = tk.Button(text='click me', command=test)
btn.pack()

root.mainloop()

my_var 将其值更改为2 时,我希望程序退出while 循环。但由于某种原因,它永远卡在那里,即使在主窗口关闭后,它似乎也没有退出wait_variable。我偶然发现了thisthis 关于它的问题,但我认为情况并非如此。这些问题的问题在于变量不变。在我的代码中,my_var 实际上正在发生变化,可以在第二个标签中看到。但进一步的执行永远不会发生。正如wait_variable description 声称的那样:“将其设置为当前值也很重要”。 所以这意味着,在第二个线程内的每次迭代之后,当它被重新分配给相同的值时 - 第一个消息框应该出现。在my_var 值更改为2 之后,应该会出现第二个消息框。但他们从不这样做。

我在这里错过了什么?

【问题讨论】:

    标签: python python-3.x windows tkinter


    【解决方案1】:

    为了让my_var 按预期工作,您必须将您的呼叫从以下位置更改为root.wait_variable

    root.wait_variable('my_var')
    

    root.wait_variable(my_var)
    

    除此之外,您可能需要将终止线程的逻辑放在胎面本身内,否则它将继续迭代直到完成。

    【讨论】:

    • 非常感谢!看起来合乎逻辑,我再次检查了wait_variable 的描述,它没有在任何地方提及字符串,所以现在我为什么使用引号似乎很愚蠢。 )
    • 为什么你认为我需要改变终止的逻辑?因为潜在的永恒循环?你的意思是超时?
    • 不客气——我不熟悉threads,但除非线程内发出某种终止信号,否则我不知道你会如何告诉它它可以终止;也许有办法,IDK。
    • 其实这很好,通常我会仔细检查以避免永恒的循环。只是我想不在这里做,因为这里的代码只是一些实验和实际的事情,我正在编写代码是检查 Windows 服务的状态是“运行”还是“停止”。如果没有(意味着它正在启动或停止),那么就等到该过程完成然后继续。所以在这里包含超时似乎没有太多意义,但我想添加一个以防万一还是不错的。我做了什么:不会伤害,哈? ;) 谢谢。
    猜你喜欢
    • 2020-11-10
    • 2021-12-11
    • 2018-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-29
    • 2021-08-22
    相关资源
    最近更新 更多