2009-05-18 90 views
1

我正在寻找相当于我的回答Tcl/Tk examples?的wxPython。具体来说,我想看一个如何创建几个按钮的例子,每个按钮在点击时运行一些外部命令。在进程运行时,我希望输出转到可滚动的wxPython小部件。wxPython:异步执行命令,在文本部件中显示stdout

当进程运行时,GUI不应该被阻塞。例如,假设其中一个按钮可以启动开发任务,如构建或运行单元测试。一个按钮被点击时

回答

5

在这里,一个完整的工作示例。

import wx 
import functools 
import threading 
import subprocess 
import time 

class Frame(wx.Frame): 
    def __init__(self): 
     super(Frame, self).__init__(None, -1, 'Threading Example') 
     # add some buttons and a text control 
     panel = wx.Panel(self, -1) 
     sizer = wx.BoxSizer(wx.VERTICAL) 
     for i in range(3): 
      name = 'Button %d' % (i+1) 
      button = wx.Button(panel, -1, name) 
      func = functools.partial(self.on_button, button=name) 
      button.Bind(wx.EVT_BUTTON, func) 
      sizer.Add(button, 0, wx.ALL, 5) 
     text = wx.TextCtrl(panel, -1, style=wx.TE_MULTILINE|wx.TE_READONLY) 
     self.text = text 
     sizer.Add(text, 1, wx.EXPAND|wx.ALL, 5) 
     panel.SetSizer(sizer) 
    def on_button(self, event, button): 
     # create a new thread when a button is pressed 
     thread = threading.Thread(target=self.run, args=(button,)) 
     thread.setDaemon(True) 
     thread.start() 
    def on_text(self, text): 
     self.text.AppendText(text) 
    def run(self, button): 
     cmd = ['ls', '-lta'] 
     proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) 
     for line in proc.stdout: 
      wx.CallAfter(self.on_text, line) 

if __name__ == '__main__': 
    app = wx.PySimpleApp() 
    frame = Frame() 
    frame.Show() 
    app.MainLoop() 
0

启动一个线程:

try: 
    r = threading.Thread(target=self.mycallback) 
    r.setDaemon(1) 
    r.start() 
except: 
    print "Error starting thread" 
    return False 

使用wx.PostEvent和wx.lib.newevent从回调将消息发送到主线程。

This link may be helpful。

+0

我很感谢您的建议,但我正在寻找一个使用wxPython的具体示例。假设我对wxPython一无所知,并且你会非常接近真相。 – 2009-05-18 20:15:39

0

布莱恩,尝试这样的事情:

import subprocess, sys 

def doit(cmd): 
    #print cmd 
    out = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True).stdout 
    return out.read() 

所以按下按钮时,该命令被使用的子模块运行,你得到的输出作为一个字符串。您可以将其分配给文本控件的值以显示它。您可能不得不out.readfully()或多次阅读以逐步显示文本。

如果按钮&的文本字段不熟悉,那么快速浏览一下wxPython demo会告诉你该怎么做。

+0

这不符合我的标准之一:“在运行过程中GUI不应该阻止”。在你的例子中,当你等待out.read()完成时,UI会被阻塞。 – 2009-06-24 01:00:07

+0

是什么让你说Bryan?你试过了吗?我的理解是你可以通过执行Popen.wait()来阻止它,但是如果你不用阻塞wait命令,你将能够通过read命令读取当时可用的任何stdout。 http://docs.python.org/library/subprocess.html – 2009-06-24 11:38:28

相关问题