4

我是 python 的初学者,它是我的第一语言。我的任务是很快变得太大,以至于我无法掌握我需要完成的事情。我快完成了。此时,我创建了一个用作主菜单的对话框,一个从主菜单中可选择的选项运行测试的对话框,以及一个运行测试的多线程实例,打开“请稍候”框并在完成测试后,弹出另一个对话框,声明测试完成。

我的问题:在“运行测试”对话框中,我试图创建一个按钮来调用多线程实例。从我在其他人的帮助下一起解析的代码中,我无法在“运行测试”对话框中看到要实例化哪个类。

我开始相信我的线程实现是不正确的。不过,一定有办法。

这是我试图调用的模块。

from slice_setup import SLICE_SETUP
import Tkinter as tk
import threading
import Queue


class GuiPart:
    def __init__(self, master, queue):
        self.queue = queue
        self.master = master
        self.master.geometry("300x100+400+250")
        self.master.title("RSAM BCT")
        tk.Label(master, text="REDCOM SLICE", fg="red").pack()
        tk.Label(master, text="BCT - Basic Configuration Test", fg= "red").pack()
        tk.Label(master, text="Please wait...", fg= "black").pack()
        tk.Label(master, text="Estimated time: 3 min 6 sec", fg= "black").pack()

    def processIncoming(self):
        while self.queue.qsize():
            try:
                text = self.queue.get(0)
                Complete(self.master, text)
            except Queue.Empty:
                pass

class ThreadedClient:
    def __init__(self, master):
        self.master = master
        self.queue = Queue.Queue()
        self.gui = GuiPart(master, self.queue)
        self.running = True
        self.thread = threading.Thread(target=self.workerThread1)
        self.thread.start()
        self.periodicCall()

    def periodicCall(self):
        self.gui.processIncoming()
        if not self.running:
            return
        self.master.after(100, self.periodicCall)

    def workerThread1(self):
        obj_rcs = SLICE_SETUP()
        obj_rcs.SLICE()
        self.queue.put("Configuration Complete!")
        self.running = False

class Complete(tk.Toplevel):
    def __init__(self, master=None, completetext=""):
        tk.Toplevel.__init__(self, master)
        self.geometry("400x300+400+250")
        self.title("RSAM BCT")
        tk.Label(self, text="REDCOME SLICE", fg="red").pack()
        tk.Label(self, text="BCT - Basic Configuration Test", fg="red").pack()
        tk.Label(self, text=completetext, fg="dark green").pack()
        tk.Label(self, text="Trunk 1: Port 1: Phone 1: 760-450-4500", fg="black").pack()
        tk.Label(self, text="Trunk 1: Port 2: Phone 2: 760-450-4501", fg="black").pack()
        tk.Button(self, text="    Exit    ", command=self.destroy).pack()


if __name__ == "__main__":
    root = tk.Tk()
    client = ThreadedClient(root)
    root.mainloop()

这就是我试图打电话的地方:

import sys
import Tkinter as Tk()
from bct_pleasewait import ????
import threading
import Queue
import time
sGui = Tk()

class slice_menu:

    def runtest(self):
        obj_wait = ????
        obj_wait.????

    def slicemenu(self):
        sGui.geometry("400x300+400+250")
        sGui.title("RSAM BCT")
        Label(sGui, text= "REDCOM SLICE", fg="red").pack()
        Label(sGui, text= "BCT - Basic Configuration Test", fg= "red").pack()
        Label(sGui, text= "-Ensure you are logged off of HyperTerminal", fg= "black").pack()
        Label(sGui, text= "-Turn on your REDCOM SLICE unit",
        fg= "black").pack()
        Label(sGui, text= "-Please connect your laptop to SLICE CONSOLE", fg= "black").pack()
        Label(sGui, text= "-This configuration will take 3 minutes", fg= "black").pack()
        Button(sGui, text = "     Run     ", command = self.runtest).pack()
        Button(sGui, text = "  Exit test  ", command = sGui.destroy).pack()
        sGui.mainloop()

这个类仍然有小错误,但我只想先解决这个问题。

4

1 回答 1

0

不是一个具体的答案,但你的问题非常广泛。

需要记住的几点:

  • Tk 不是线程安全的。也就是说,您应该从主线程调用 Tk 调用。可以让其他线程做非gui工作。
  • 在 CPython 中,由于全局解释器锁(“GIL”),一次只能有一个线程执行 Python 字节码。因此,您的非 gui 线程可能会使 GUI 无响应。

如果您一次只运行一个测试,并且可以将该测试分成小块,则可以使用超时(也称为警报处理程序)。这个处理程序做了一些工作,保存它的状态,更新进度对话框然后退出,等待再次调用。

如果测试运行很长时间并且您希望 GUI 保持响应,我建议使用多处理而不是线程。在不同的进程中开始您的测试,并使用诸如队列和信号量之类的东西在 GUI 和非 qui 进程之间进行通信。

于 2013-07-19T13:09:15.730 回答