Reputation:
Despite seeing many questions being asked about this very topic, I can not find a suitable answer for my quandary. I am a beginner at Python and it is my first language. I am trying to create a dialog box that runs a test automatically on opening the box. When the test finishes, I want another dialog box to open which states the test is complete. The test is functional and runs properly. However, since the secondary dialog is calling a second instance of Tk()
, it will not open.
My Question: How can I change my code in order to allow the secondary dialog box to open on completion of my test?
obj_rcs
is the test being run.
obj_config
is the secondary dialog box.
My Code:
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()
Upvotes: 1
Views: 3822
Reputation: 20679
It looks like the problem is that you are creating another Tk element when you call the functions in the other modules, since you don't pass the one you create to the complete()
function. Thus, it should accept a master
argument, and then use it in the other module and then avoid multiple root Tk elements.
Besides, you are using more than one geometry manager (place
and pack
). You should use only one in the same window to avoid unexpected behaviour. Besides, this methods always return None
, so the assignments like plabel = ...
are useless - not only because it stores None
but also because it may be misleading.
EDIT: I've added a modification of your code so you can have an overview of how to communicate with the spawn thread. I have not tested it, but at least it can be a reference to get the general idea.
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()
Upvotes: 2