2013-08-06 31 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