Python Tkinter螺纹
尽管有人就这个问题问了很多问题,我还是找不到一个合适的答案来解决我的困惑。我是Python的初学者,它是我的第一语言。我正在尝试创建一个对话框,在打开该对话框时自动运行测试。测试完成后,我希望打开另一个对话框,说明测试已完成。测试功能正常,运行正常。但是,由于辅助对话框正在调用Python Tkinter螺纹,python,multithreading,tkinter,Python,Multithreading,Tkinter,尽管有人就这个问题问了很多问题,我还是找不到一个合适的答案来解决我的困惑。我是Python的初学者,它是我的第一语言。我正在尝试创建一个对话框,在打开该对话框时自动运行测试。测试完成后,我希望打开另一个对话框,说明测试已完成。测试功能正常,运行正常。但是,由于辅助对话框正在调用Tk()的第二个实例,因此它不会打开 我的问题:如何更改代码,以便在测试完成时打开辅助对话框 obj_rcs是正在运行的测试。 obj_config是辅助对话框 我的代码: enter code here from con
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元素,因为您没有将创建的Tk元素传递给
complete()
函数。因此,它应该接受一个master
参数,然后在其他模块中使用它,然后避免使用多个根Tk元素
此外,您正在使用多个几何图形管理器(place
和pack
)。您应该在同一窗口中只使用一个窗口,以避免意外行为。此外,这种方法总是返回None
,因此像plabel=…
这样的赋值是无用的——不仅因为它存储None
,而且还因为它可能会产生误导
编辑:我添加了对代码的修改,这样您就可以大致了解如何与spawn线程通信。我还没有测试过它,但至少它可以作为一个参考,以获得大致的想法
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()
小心你的术语。“同一个窗口”是模糊的。你说的“窗口”是什么意思?小部件?顶层窗户?您不应该在同一个容器小部件中混合它们,但是在同一个应用程序中混合它们是可以的。如果您使用“窗口”来表示整个窗口,包括其所有子窗口小部件,那么将它们混合在同一窗口中是很好的。如果你真的是指
Tk
或Toplevel
@BryanOakley的同一个实例,那么混用它们是不好的。我使用了“窗口”这个词,因为文档中也使用了这个术语来指代根窗口和Toplevel小部件:,如何创建辅助对话框的主参数?@georgelongren这取决于如何创建对话框:如果是顶级小部件,请将主参数作为构造函数的第一个参数传递。如果它是对tkMessageBox
函数的调用,则不需要它,但问题的原因不同。@a.Rodas我已将要引用的类添加到代码中。我已经知道它现在甚至不起作用,因为我试图在某些地方切换某些值。请原谅我缺乏理解,但除非我做错了,否则通过主要论点对我不起作用。