2013-08-06 4 views
1

현재 easygui를 사용하여 사용자 입력을받는 스크립트를 실행 중입니다. 커맨드 라인에서 실행 된 이전 스크립트는 사용자가 명령 행에서 알아야 할 모든 것을 인쇄 할 것이지만, 필자는 입력이 필요할 때 새로운 easygui 박스에서 알림을 출력하도록 변경했습니다.easygui 텍스트 상자에 쓰기 기능이 실행 중입니까?

원하는 작업이 진행되고 있고, 실행중인 함수 안에있는 각 작업이 완료되면 텍스트 상자에 인쇄됩니다. 커맨드 라인에서 나는 단지 print "text"을 사용할 수 있었지만, easygui에서 실시간으로 실행되도록 할 수는 없습니다. 현재 모든 것이 완료되면 함수의 결과를 표시하는 텍스트 상자가 있으므로 목록을 추가하고 있습니다. 그러나 노트 작성 프로세스가 완료 될 때마다 큰 텍스트 상자 창이 튀어 나와서 줄을 인쇄하고 싶습니다. 이게 가능합니까? 여기

내가 목록을 추가하고있어 방법은 다음과 같습니다

result_list = [] 
record_str = "\n Polling has completed for 502." 
result_list.append(record_str) 
eg.textbox("Polling Status", "Daily polling completion status:", result_list) 

답변

3

난 당신이 모듈을 수정하는 짧은 원하는 일을하기에는 EasyGUI의 textbox 기능을지고의 간단한 방법이 있다고 생각하지 않습니다. 클래스가 아닌 함수이기 때문에 쉽게 코드를 재사용하기 위해 하위 클래스를 파생 할 수 없습니다.

뉴스 그룹의 스레드에서 한 번 발견 된 일부 코드의 향상된 버전을 사용하여 텍스트 줄을 표시하는 별도의 Tkinter 창을 만드는 것이 가능합니다.

원래 코드는 출력 핸들이없는 GUI 응용 프로그램에서만 stderr 출력을 캐치하고 표시하도록 설계되었으므로 모듈의 이름은 errorwindow입니다. 그러나 나는 stderrstdout을 하나의 easygui 기반 응용 프로그램에서 이러한 창으로 리다이렉트 할 수 있도록 수정했는데, 이름을 바꾸거나 주석을 업데이트하여 주위를 돌아 보지 못했습니다. stdout 리다이렉션. ;¬)

어쨌든, 모듈 정의하고 import 에드 때 OutputPipe라는 이름의 파일과 같은 클래스의 두 인스턴스를 작성하여 작품과 파이썬 .pyw에 보통 Nonesys.stdoutsys.stderr I/O 스트림 파일 오브젝트에 할당 GUI 응용 프로그램 (Windows). 출력이 처음에 이들 중 하나에 전송되면 동일한 모듈이 stdin, stdoutstderr 입출력 핸들이 원래 프로세스와 연결된 별도의 Python 프로세스로 실행됩니다.

많은 일이 벌어지고 있지만 그 밖의 것이 없다면 조금 연구하면 easygui 님의 textbox에게 원하는 것을 할 수있는 방법에 대한 아이디어를 줄 수 있습니다. 희망이 도움이됩니다.

참고 : 게시 된 코드는 파이썬 2.x를위한는 누구나 관심이 있다면, 다른 질문에 my answer 모두 파이썬 2와 3에서 작동 수정 된 버전이있다.

파일 errorwindow.py :

# references: 
# https://groups.google.com/d/msg/comp.lang.python/HWPhLhXKUos/TpFeWxEE9nsJ 
# https://groups.google.com/d/msg/comp.lang.python/HWPhLhXKUos/eEHYAl4dH9YJ 
# 
# Here's a module to show stderr output from console-less Python 
# apps, and stay out of the way otherwise. I plan to make a ASPN 
# recipe of it, but I thought I'd run it by this group first. 
# 
# To use it, import the module. That's it. Upon import it will 
# assign sys.stderr. 
# 
# In the normal case, your code is perfect so nothing ever gets 
# written to stderr, and the module won't do much of anything. 
# Upon the first write to stderr, if any, the module will launch a 
# new process, and that process will show the stderr output in a 
# window. The window will live until dismissed; I hate, hate, hate 
# those vanishing-consoles-with-critical-information. 
# 
# The code shows some arguably-cool tricks. To fit everthing in 
# one file, the module runs the Python interpreter on itself; it 
# uses the "if __name__ == '__main__'" idiom to behave radically 
# differently upon import versus direct execution. It uses TkInter 
# for the window, but that's in a new process; it does not import 
# TkInter into your application. 
# 
# To try it out, save it to a file -- I call it "errorwindow.py" - 
# - and import it into some subsequently-incorrect code. For 
# example: 
# 
#  import errorwindow 
# 
#  a = 3 + 1 + nonesuchdefined 
# 
# should cause a window to appear, showing the traceback of a 
# Python NameError. 
# 
# -- 
# --Bryan 
# ---------------------------------------------------------------- 
# 
# martineau - Modified to use subprocess.Popen instead of the os.popen 
#    which has been deprecated since Py 2.6. Changed so it 
#    redirects both stdout and stderr. Added numerous 
#    comments, and also inserted double quotes around paths 
#    in case they have embedded space characters in them, as 
#    they did on my Windows system. 

""" 
    Import this module into graphical Python apps to provide a 
    sys.stderr. No functions to call, just import it. It uses 
    only facilities in the Python standard distribution. 

    If nothing is ever written to stderr, then the module just 
    sits there and stays out of your face. Upon write to stderr, 
    it launches a new process, piping it error stream. The new 
    process throws up a window showing the error messages. 
""" 
import subprocess 
import sys 
import thread 
import os 

if __name__ == '__main__': # when spawned as separate process 
    # create window in which to display output 
    # then copy stdin to the window until EOF 
    # will happen when output is sent to each OutputPipe created 
    from Tkinter import BOTH, END, Frame, Text, TOP, YES 
    import tkFont 
    import Queue 

    queue = Queue.Queue(100) 

    def read_stdin(app, bufsize=4096): 
     fd = sys.stdin.fileno() # gets file descriptor 
     read = os.read 
     put = queue.put 
     while True: 
      put(read(fd, bufsize)) 

    class Application(Frame): 
     def __init__(self, master=None, font_size=8, text_color='#0000AA', rows=25, cols=100): 
      Frame.__init__(self, master) 
      # argv[0]: name of this script (not used) 
      # argv[1]: name of script that imported this module 
      # argv[2]: name of redirected stream (optional) 
      if len(sys.argv) < 3: 
       title = "Output Stream from %s" % (sys.argv[1],) 
      else: 
       title = "Output Stream '%s' from %s" % (sys.argv[2], sys.argv[1]) 
      self.master.title(title) 
      self.pack(fill=BOTH, expand=YES) 
      font = tkFont.Font(family='Courier', size=font_size) 
      width = font.measure(' '*(cols+1)) 
      height = font.metrics('linespace')*(rows+1) 
      self.configure(width=width, height=height) 
      self.pack_propagate(0) # force frame to be configured size 
      self.logwidget = Text(self, font=font) 
      self.logwidget.pack(side=TOP, fill=BOTH, expand=YES) 
      # Disallow key entry, but allow copy with <Control-c> 
      self.logwidget.bind('<Key>', lambda x: 'break') 
      self.logwidget.bind('<Control-c>', lambda x: None) 
      self.logwidget.configure(foreground=text_color) 
      #self.logwidget.insert(END, '==== Start of Output Stream ====\n\n') 
      #self.logwidget.see(END) 
      self.after(200, self.start_thread,()) 

     def start_thread(self, _): 
      thread.start_new_thread(read_stdin, (self,)) 
      self.after(200, self.check_q,()) 

     def check_q(self, _): 
      log = self.logwidget 
      log_insert = log.insert 
      log_see = log.see 
      queue_get_nowait = queue.get_nowait 
      go = True 
      while go: 
       try: 
        data = queue_get_nowait() 
        if not data: 
         data = '[EOF]' 
         go = False 
        log_insert(END, data) 
        log_see(END) 
       except Queue.Empty: 
        self.after(200, self.check_q,()) 
        go = False 

    app = Application() 
    app.mainloop() 

else: # when module is first imported 
    import traceback 
    class OutputPipe(object): 
     def __init__(self, name=''): 
      self.lock = thread.allocate_lock() 
      self.name = name 

     def __getattr__(self, attr): 
      if attr == 'pipe': # pipe attribute hasn't been created yet 
       # launch this module as a separate process to display any output 
       # it receives. 
       # Note: It's important to put double quotes around everything in case 
       # they have embedded space characters. 
       command = '"%s" "%s" "%s" "%s"' % (sys.executable,    # command 
                __file__,      # argv[0] 
                os.path.basename(sys.argv[0]), # argv[1] 
                self.name)      # argv[2] 

       # sample command and arg values on receiving end: 
       # E:\Program Files\Python\python[w].exe       # command 
       # H:\PythonLib\TestScripts\PyRemindWrk\errorwindow.py   # argv[0] 
       # errorwindow.py            # argv[1] 
       # stderr              # argv[2] 

       # execute this script as __main__ with a stdin PIPE for sending output to it 
       try: 
        # had to make stdout and stderr PIPEs too, to make it work with pythonw.exe 
        self.pipe = subprocess.Popen(command, bufsize=0, 
               stdin=subprocess.PIPE, 
               stdout=subprocess.PIPE, 
               stderr=subprocess.PIPE).stdin 
       except Exception: 
        # output exception info to a file since this module isn't working 
        exc_type, exc_value, exc_traceback = sys.exc_info() 
        msg = ('%r exception in %s\n' % 
          (exc_type.__name__, os.path.basename(__file__))) 
        with open('exc_info.txt', 'wt') as info: 
         info.write('msg:' + msg) 
         traceback.print_exc(file=info) 
        sys.exit('fatal error occurred spawning output process') 

      return super(OutputPipe, self).__getattribute__(attr) 

     def write(self, data): 
      with self.lock: 
       self.pipe.write(data) # 1st reference to pipe attr will cause it to be created 

    # redirect standard output streams in the process importing the module 
    sys.stderr = OutputPipe('stderr') 
    sys.stdout = OutputPipe('stdout') 
+0

은 그 그것을 할 것입니다, 감사합니다! – Benjooster