簡體   English   中英

Python通過線程tkinter進行通信

[英]Python communicate through threads tkinter

我正在創建一個基於文本的游戲,並且想知道它已經運行了多少秒,這是我第一次使用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()

您遇到的部分問題是,不能保證gui線程將在計數器線程運行之前初始化。 為了解決這個問題,除了創建線程的線程之外,您無法從任何線程安全地訪問tkinter控件。 因此,即使您解決了啟動順序問題,您仍然還有其他問題要解決。

好消息是,您不需要線程即可解決此問題。 實際上,線程使這個問題更加困難。

如果要每秒運行某件事,請使用after來調用一個函數,然后在after使用該函數來安排自己在一秒鍾內再次運行。

這是一個粗糙的例子:

   def counter():
        global uptime
        uptime += 1
        upt_label['text'] = 'Uptime: %s' % uptime
        root.after(1000, counter)

請注意,此函數將如何更新標簽,然后安排自己在一秒鍾后再次調用。 這可能會有一點誤差,因為不能保證精確地運行一秒鍾。 一種更准確的解決方案是節省程序啟動的時間,然后獲取當前時間並做一些數學運算。 這將使您在長時間運行的程序中得到更准確的表示。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM