wxPython - 在textctrl小部件中捕获shell输出?

时间:2011-07-10 02:28:03

标签: wxpython subprocess textctrl

我正在同时学习python和wxPython ...... :)所以,我有一组从命令行运行良好的python文件:./scan -d test ~/Pictures - 例如将创建一个数据库我的照片叫做“测试”。

我一直在为前端努力工作(我没有编写原始的命令行python文件),我可以使用它来运行:

def bt_ScanUpdateClick(self, event):
    self.SetSizeWH(450,360)

    ## DEBUG
    self.tc_MainDatabase.Value = "test.db"


    if self.tc_MainDatabase.Value == "":
        self.LogWindow.Value += "ERROR:\tNo database name selected!\n"
    else:
        scanCMD = "./scan -d " + self.tc_MainDatabase.Value + " "

        numLines=0
        maxLines=(int(self.multiText.GetNumberOfLines()))

        if self.multiText.GetLineText(numLines) == "":
            self.LogWindow.Value += "ERROR\tNo folder selected to scan!\n"
        else:
            self.LogWindow.Value += "Running Scan...\n\n"
            while (numLines < maxLines):
                scanCMD += str(self.multiText.GetLineText(numLines)) + " "
                numLines += 1

            self.LogWindow.Value += scanCMD

            p = subprocess.Popen([scanCMD],shell=True,stdout=subprocess.PIPE,stdin=subprocess.PIPE)
            self.LogWindow.Value += p.communicate()[0]

这给我带来了一个问题:

  1. 点击按钮激活后 实际上,它实际上并没有得到 自我.SetSizeWH(450,360)部分 功能。它只是停留在一个 “向下”状态。什么时候 命令完成,应用程序来了 恢复生活中的一切 输出窗口(self.LogView)已经......我愿意 喜欢把输出更多 “实时”的方式......可能吗?
  2. 有什么想法吗?

1 个答案:

答案 0 :(得分:1)

粗略地说,在事件循环的每次迭代期间都会发生屏幕更新。当您的代码正在运行时,事件循环会停留在同一个迭代中,因此不会发生屏幕更新。

要解决此问题,您需要在单独的线程或进程中运行长时间运行的任务。因为wxPython是单线程的,所以对GUI的任何更新(例如编写输出行)都必须在主线程中完成。为此,您的工作线程可以使用wx.CallAfter,它将安排一个命令在GUI线程中尽早运行。

有关详细信息,请参阅wxPython wiki上的页面Long Running Tasks,并在此网站上查看问题this answerwxPython: Problems with thread.