python - Tkinter 线程

标签 python multithreading tkinter

尽管看到很多关于这个主题的问题,但我找不到合适的答案来解决我的困境。我是 Python 的初学者,它是我的第一语言。我正在尝试创建一个对话框,在打开该框时自动运行测试。测试完成后,我希望打开另一个对话框,表明测试已完成。测试功能正常且运行正常。但是,由于辅助对话框正在调用 Tk() 的第二个实例,因此它不会打开。

我的问题:如何更改代码以便在测试完成时打开辅助对话框?

obj_rcs 是正在运行的测试。 obj_config 是辅助对话框。

我的代码:

enter code here
from configcomplete_slice import complete
from slice_setup import SLICE_SETUP
import Tkinter
import threading
import Queue

class GuiPart:

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


    def processIncoming(self):
        while self.queue.qsize():
            try:
                msg = self.queue.get(0)
                print msg
            except Queue.Empty:
                pass

class ThreadedClient:

    def __init__(self, master):
        self.master = master
        # Create the queue
        self.queue = Queue.Queue()
        # Set up the GUI part
        self.gui = GuiPart(master, self.queue)
        # Set up the thread to do asynchronous I/O
        self.running = 1
        self.thread1 = threading.Thread(target = self.workerThread1)
        self.thread1.start()
        self.periodicCall()

    def periodicCall(self):
        self.gui.processIncoming()
        if not self.running:
            import sys
            sys.exit(1)
        self.master.after(100, self.periodicCall)

    def workerThread1(self):
        while self.running:
            obj_rcs = SLICE_SETUP()
            obj_com = complete()

            obj_rcs.SLICE()
            obj_com.config()

root = Tkinter.Tk()
client = ThreadedClient(root)
root.mainloop()

class complete:

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

最佳答案

看起来问题在于,当您调用其他模块中的函数时,您正在创建另一个 Tk 元素,因为您没有将创建的元素传递给 complete() 函数。因此,它应该接受 master 参数,然后在其他模块中使用它,然后避免多个根 Tk 元素。

此外,您正在使用多个几何管理器(placepack)。您应该在同一窗口中仅使用一个,以避免意外行为。此外,此方法始终返回 None,因此像 plabel = ... 这样的赋值是无用的 - 不仅因为它存储 None,还因为这可能会产生误导。

<小时/>

编辑:我添加了对您的代码的修改,以便您可以大致了解如何与生成线程进行通信。我没有测试过,但至少可以作为一个引用,大致了解一下。

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 = Tkinter.Tk()
    client = ThreadedClient(root)
    root.mainloop()

关于python - Tkinter 线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17167283/

相关文章:

python - 从wheel安装加密2.2.1或更高版本

python - 如何根据某些条件转换(长到宽)数据框

python - Django 可以将多个 LDAP 身份验证映射到单个 User 对象吗?

javascript - 了解事件循环

java - 使用 AsyncHttpClient 和 Quartz Job 疯狂运行的线程

python - 如何交互地更改动画参数

java - 如何将 python 模块添加到 jython/lib 中?

python:与 pandas 一起工作。获取计数

Python Tkinter 程序无法正确将数据发送到我的文本文件

multithreading - 将参数传递给 threading.Thread