2013-06-18 3 views
1

이 주제와 관련하여 많은 질문을했지만, 필자는 필자의 질문에 대해 적절한 대답을 찾을 수 없습니다. 저는 파이썬에서 초보자이며 제 첫 번째 언어입니다. 상자를 열 때 자동으로 테스트를 실행하는 대화 상자를 만들려고합니다. 테스트가 끝나면 테스트가 완료된 다른 대화 상자를 열어야합니다. 이 테스트는 기능적으로 올바르게 실행됩니다. 그러나 보조 대화 상자가 Tk()의 두 번째 인스턴스를 호출하기 때문에 열리지 않습니다.Tkinter threading

내 질문 : 내 테스트가 끝나면 보조 대화 상자를 열 수 있도록 코드를 어떻게 변경합니까?

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() 

답변

3

당신이 다른 모듈에서 함수를 호출 할 때 당신이 complete()에 만든 하나를 통과하지 않기 때문에 당신이 다른 Tk의 요소를 만드는 것입니다 기능. 따라서, 인수는 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() 
+0

용어에주의하십시오. "같은 창"은 모호합니다. "창"이란 무엇을 의미합니까? 위젯? 탑 레벨 윈도우? 같은 컨테이너 위젯에 이들을 섞어서는 안되지만 동일한 응용 프로그램에서 혼합하는 것이 좋습니다. "창"을 사용하여 모든 하위 위젯을 포함하여 창 전체를 의미하는 경우 동일한 창에서 이들을 혼합하는 것이 좋습니다. 만약 당신이 실제로'Tk' 나'Toplevel'의 동일한 인스턴스를 의미한다면 그것들을 혼합하는 것은 나쁘다. –

+0

@BryanOakley이 용어는 설명서에서 루트 창과 Toplevel 위젯 (http://www.pythonware.com/library/tkinter/introduction/application-windows)을 참조하기 위해 사용되기 때문에 "window"라는 단어를 사용했습니다. htm, http://effbot.org/tkinterbook/wm.htm –

+0

보조 대화 상자의 마스터 인수를 어떻게 만듭니 까? –