2017-05-01 1 views
0

스크립트가 실행되는 동안 로그 라인을 화면에 표시하는 우아한 방법을 찾고 있습니다.병렬 GUI를 사용하여 화면에 로그 라인을 표시

from time import sleep 
from threading import Thread 
import tkinter as tk 


class WaitGuiPrallel(Thread): 
    def __init__(self, TXT='Wait!', ttl='Logs'): 
     self.txt = TXT 
     Thread.__init__(self) 
     self.ttl = ttl 
     self.start() # This is starting the self.run() 

    def run(self): 
     self.root = tk.Tk() 
     self.root.attributes("-topmost", True) 
     self.root.title(self.ttl) 
     self.label = tk.Label(self.root, text=self.txt, font=("Helvetica", 20)) 
     self.label.pack() 
     self.Location() 
     self.root.mainloop() 

    def Exit(self): 
     self.root.quit() 

    def Location(self): 
     w = 500 # width for the Tk root 
     h = 150 # height for the Tk root 
     ws = self.root.winfo_screenwidth() # width of the screen 
     self.root.geometry('%dx%d+%d+%d' % (w, h, ws - w - 20, 10)) 

    def Update(self, newText): 
     self.txt1 = newText 
     self.label.destroy() 
     self.label = tk.Label(self.root, text=self.txt1, 
           font=("Helvetica", 12)) 
     self.label.pack() 
     self.root.update() 

Wait = WaitGuiPrallel(TXT='Wait! Do not touch mouse or keyboard') 
sleep(2) 
for t in range(5): 
    sleep(1) 
    Wait.Update(newText='Log line %s' % t) 
Wait.Update(newText='Done!') 
sleep(1) 
Wait.Exit() 

현재 스크립트는 몇 가지 문제가 있어요 : 그것은 우아한되지 않습니다

  1. 을 - 다른 스레드에서 업데이트 할 때이 문제가 더 나은 방법

  2. 이 있어야

  3. Spyder + IPython에서 두 번 실행하는 것은 불가능합니다 (IPython 동결)

+0

2 개의 창을 동시에 열어 보시겠습니까? 쓰레드는 잊어 버리십시오. 두 번째 윈도우를 만들기 위해'tk.Topvel'을 사용하십시오. – Novel

답변

0

Tkinter는 스레드와 잘 맞지 않습니다. StringVar를 사용하면 (내 경험에 비추어) 다른 메서드보다 좀 더 스레드 친화적입니다. 여기에 더하여 몇 가지 다른 수정을 수행하는 방법은 다음과 같습니다

from time import sleep 
from threading import Thread 
import tkinter as tk 

class WaitGuiPrallel(Thread): 
    def __init__(self, TXT='Wait!', ttl='Logs'): 
     Thread.__init__(self) 
     self.txt = TXT 
     self.ttl = ttl # what's this for? 
     self.daemon = True # this thread will terminate when the main thread terminates 
     self.start() # This is starting the self.run() 

    def run(self): 
     self.root = tk.Tk() 
     self.root.attributes("-topmost", True) 
     self.root.title(self.ttl) 
     self.txt = tk.StringVar(value=self.txt) 
     self.label = tk.Label(self.root, textvariable=self.txt, font=("Helvetica", 20)) 
     self.label.pack() 
     self.Location() 
     self.root.mainloop() 

    def Location(self): 
     w = 500 # width for the Tk root 
     h = 150 # height for the Tk root 
     ws = self.root.winfo_screenwidth() # width of the screen 
     self.root.geometry('%dx%d+%d+%d' % (w, h, ws - w - 20, 10)) 

Wait = WaitGuiPrallel(TXT='Wait! Do not touch mouse or keyboard') 
sleep(2) 
for t in range(5): 
    sleep(1) 
    Wait.txt.set('Log line %s' % t) 
Wait.txt.set('Done!') 
sleep(1) 

이 다음 내가 큐를 ​​모니터링하는 큐 제 3 스레드를 사용하는 것이 좋습니다 것입니다 다중 스레드 호출이있는 경우.

+0

해답을 보내 주셔서 감사합니다. 그러나 귀하의 스크립트가 (내 컴퓨터에서) 작동하지 않습니다. 'Wait.txt.set (...)'을 만들 수 없으며 'Wait.txt ='로그 라인 % s '% t'으로 변경하면 업데이트되지 않고 마지막에 위젯을 닫지 않습니다 . – user1889297

+0

나는 그것을 테스트하고 나를 위해 작동합니다. 오류 메시지가 나타 납니까? 'Wait.txt = 'Log line % s'% t ''에서 작동하도록 구문을 변경하려면 속성 설정자를 만들어야합니다. – Novel

+0

Spyder + IPython을 사용할 때 처음 실행 중이지만 두 번째 실행시 오류가 발생합니다 : RuntimeError : 주 스레드가 주 루프에 없습니다 – user1889297

관련 문제