2013-08-06 21 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窗口,只需在使用comp.lang.python新聞組的一個線程中發現的一些代碼的增強版本發送給它時顯示文本行,這是完全可行的。

原始代碼被設計爲捕捉並顯示只有stderr輸出從GUI應用程序,通常沒有stderr輸出句柄,因此該模塊被命名爲errorwindow。然而,我修改了它可以將stderrstdout重定向到我開發的一個基於easygui的應用程序中的這些窗口,但我從未想過將其重命名或更新其中的註釋以提及stdout重定向。​​

不管怎樣,模塊的工作原理是定義和創建命名OutputPipe時,它的import編一個類文件類的兩個實例,並將它們分配給sys.stdoutsys.stderr I/O流文件通常是None在Python .pyw對象GUI應用程序(在Windows上)。當輸出首先發送到其中任何一個時,相同的模塊將作爲單獨的Python進程啓動,其stdin,stdoutstderr I/O句柄與原始進程一起傳送。

有很多事情要做,但如果沒有別的,稍加研究它可能會給你一些關於如何讓easyguitextbox做你想做的事情的想法。希望這可以幫助。

注:發佈的代碼是爲Python 2.x中,有一個修改版本,將在這兩個Python 2和3工作,my answer到另外一個問題,如果有人有興趣。

文件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