在主任务(Tkinter GUI)中显示后台任务的计数变量

2024-07-07 08:28:00 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图在我的tkinter GUI主任务中显示一个后台任务的count变量。为什么?我想显示正在执行的长时间后台任务,然后使用这个count变量以进度条显示它。在

我的问题是,即使使用Queue,我也不能显示count变量。也许我在理解python及其对象和/或线程的行为方面遇到了一些问题。在

import threading
import time
import Queue
import Tkinter as Tk
import Tkconstants as TkConst
from ScrolledText import ScrolledText
from tkFont import Font
import loop_simulation as loop

def on_after_elapsed():
    while True:
        try:
            v = dataQ.get(timeout=0.1)
        except:
            break
        scrText.insert(TkConst.END, str(v))     # "value=%d\n" % v
        scrText.see(TkConst.END)
        scrText.update()
    top.after(100, on_after_elapsed)

def thread_proc1():
    x = -1
    dataQ.put(x)
    x = loop.loop_simulation().start_counting()
    # th_proc = threading.Thread(target=x.start_counting())
    # th_proc.start()

    for i in range(5):
        for j in range(20):
            dataQ.put(x.get_i())
            time.sleep(0.1)
            # x += 1
        time.sleep(0.5)
    dataQ.put(x.get_i())

top = Tk.Tk()
dataQ = Queue.Queue(maxsize=0)
f = Font(family='Courier New', size=12)
scrText = ScrolledText(master=top, height=20, width=120, font=f)
scrText.pack(fill=TkConst.BOTH, side=TkConst.LEFT, padx=15, pady=15, expand=True)

th = threading.Thread(target=thread_proc1)
th.start()
top.after(100, on_after_elapsed)
top.mainloop()
th.join()

thread_proc1()中,我想得到后台任务的计数器的值。这是后台任务:

^{pr2}$

Tags: importlooptimequeuetopascountstart
1条回答
网友
1楼 · 发布于 2024-07-07 08:28:00

count变量未显示的原因是

    x = loop.loop_simulation().start_counting()

thread_proc1()中的语句。这将创建一个loop_simulation实例并调用其start_counting()方法。但是,除了已经在dataQ中插入-1之外,thread_proc1()start_counting()返回之前不会执行任何其他操作,这不会持续很长时间(500K秒)。在

同时,脚本的其余部分正在运行,并且只显示放入的初始-1。在

还要注意,如果start_counting()确实返回了,那么它的None的值将被分配给x,后面的代码试图与:x.get_i()一起使用。在

下面是对修复这些问题的代码的重新编写,并更紧密地遵循PEP 8 - Style Guide for Python Code。为了避免调用start_counting()的主要问题,我将您的loop_simulation类改为threading.Thread的子类,并将其重命名为LoopSimulation,并在thread_proc1中创建它的一个实例,因此现在除了处理基于tkinter的GUI的主线程外,还有两个后台线程。在

^{pr2}$

loop_simulation.py模块:

import threading
import time

class LoopSimulation(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
        self.daemon = True  # OK for main to exit even if instance still running
        self.lock = threading.Lock()
        self.j = 0

    start_counting = threading.Thread.start  # an alias for starting thread

    def run(self):
        for i in range(1000000):
            with self.lock:
                self.j = i
            time.sleep(0.5)

    def get_i(self):
        with self.lock:
            return self.j

相关问题 更多 >