我正在创建一个基于文本的游戏,并且想要计算它运行了多少秒,这是我第一次使用tkinter,所以我不能完全确定我是否正确地完成了这一切。当我尝试使用counter()函数更新upt_label['text']
和upt_table
时,我遇到了以下问题。
这是使用python 3.3,我需要引用什么才能在counter()中更改该变量?
from tkinter import *
import time
from threading import Thread
global upt_label
class OutBox(Frame):
def __init__(self, parent):
Frame.__init__(self, parent, background="black")
self.parent = parent
self.initUI()
def initUI(self):
self.parent.title("Text Adventure!")
self.pack(fill=BOTH, expand=1)
tpp_label = Label(self, text="Text Adventure!", fg="white", background="black", anchor="center", font=("Arial", 18))
tpp_label.pack()
upt_label = Label(self, text = "Uptime: 0", fg="white", background="black", anchor="center", font=("Arial", 12))
upt_label.pack()
def main():
root = Tk()
root.geometry("560x720")
app = OutBox(root)
root.mainloop()
def counter():
uptime = 0
while True:
upt_label['text'] = 'Uptime: %s' % uptime
time.sleep(1)
uptime = uptime + 1
gui_thread = Thread(target = main, args = ())
gui_thread.start()
upt_thread = Thread(target = counter, args = ())
upt_thread.start()
答案 0 :(得分:3)
你遇到的部分问题是无法保证gui线程会在你的计数器线程运行之前初始化。要解决问题,您无法从创建它们的线程以外的任何线程安全地访问tkinter小部件。因此,即使您解决了启动顺序问题,您仍然需要解决其他问题。
好消息是,你不需要线程来解决这个问题。事实上,线程使这个问题更难。
如果您想每秒运行一次,请使用after
来调用函数,然后让该函数使用after
来安排自己在一秒钟内再次运行。
这是一个粗略的例子:
def counter():
global uptime
uptime += 1
upt_label['text'] = 'Uptime: %s' % uptime
root.after(1000, counter)
注意这个函数如何更新标签,然后安排自己在一秒钟后再次调用。这可能有一点不准确,因为它不能保证在一秒之后精确运行。更准确的解决方案是节省程序启动的时间,然后获取当前时间并进行一些数学计算。这将使您在长期运行的程序中更准确地表示。