tkinter在循环中更改stringvar但对窗口没有影响

时间:2018-05-12 02:02:46

标签: python tkinter

我想按tk中的按钮每秒更换标签:

$(document).ready(function(){

var date = new Date();
date.setDate(date.getDate() + 1);
$("#myDate").val(date);
});

我的控制台输出是正确的,但它对windows.WHY无效?

2 个答案:

答案 0 :(得分:0)

您可以在单独的线程中启动test()函数,如下所示:

# --coding:utf-8 -----
from Tkinter import *
import time
import random
import threading

def startThread(a):
    threading.Thread(target=test, args=(a,)).start()

def test(a):
    begin =time.time()
    end =time.time()
    while True:
        ran = random.random()
        after = time.time()
        if(after-begin >1):
            a.set(str(ran))
            print a.get()
            begin =after
        if(after-end>10):
            a.set('over')
            break


t = Tk()
a = StringVar()
a.set('0')
b = Label(t,textvariable = a)
b.pack()
Button(t,text ='test',command = lambda x=a:startThread(a)).pack()


t.mainloop()

但是,即使关闭窗口,线程也不会在10秒结束前结束。您需要找到while循环的一些代码来检查应用程序是否仍在运行。

答案 1 :(得分:0)

创建必须在给定时间段内执行的行为是一个常见问题;你可以用专门的Waiter课来解决它;这样可以避免使用tkinter支持不佳的线程。

以下示例打开一个带有标签和按钮的窗口。按下按钮时,标签将每秒更新10秒钟,然后停止 在10秒内再次按下按钮无效;之后,它会重启该过程10秒钟。

import Tkinter as tk    # tkinter if python >= 3 

import time
import random


class Waiter(object):

    def __init__(self, waiting_time):
        """
        :param waiting_time: int, in seconds
        """
        self.waiting_time = waiting_time
        self.expiring_time = time.time() + self.waiting_time
        self.waiting = True
        # print('waiter started')

    def stop(self):
        # print('waiter stopping')
        self.expiring_time = None
        self.waiting = False

    def is_waiting(self):
        """returns True while waiting, false otherwise"""
        if time.time() > self.expiring_time:
            self.stop()
        return self.waiting


def atest():
    global waiter
    if waiter is None:
        waiter = Waiter(10)
        _atest()


def _atest():
    """ equivalent to: 
    while the waiter is waiting, 
    change the label every second),
    then destroy the waiter
    """
    global waiter
    if waiter.is_waiting():
        a.set(random.random())
        # print(time.time())
        t.after(1000, _atest)
    else:
        waiter = None


if __name__ == '__main__':

    waiter = None
    t = tk.Tk()
    a = tk.StringVar()
    a.set('0')
    tk.Label(t, textvariable=a).pack()
    tk.Button(t, text='test', command=atest).pack()

    t.mainloop()

注意:

你可以使_atest成为atest的内部函数,但也许它更容易理解?

使用import Tkinter as tk代替from Tkinter import *可以防止命名空间混乱,并且可以说代码更清晰。
您应该考虑使用python 3.