如何在子进程期间和之后执行操作

2024-04-23

我有一个调用子程序的程序。当子程序使用 Popen 运行时,我需要禁用运行按钮并启用停止按钮。但是,由于Popen打开了一个新进程,因此程序完成后应该打印的内容会立即打印出来。我尝试添加self.p.communicate() after Popen,但 GUI 将冻结直到子程序运行完毕,因此停止按钮将不起作用。 这是我的程序:

def gui(QtGui.QWidget):
    ...
    self.runButton = QtGui.QPushButton('Run')
    self.stopButton = QtGui.QPushButton('Stop')

    self.runButton.clicked.connect(self.run)
    self.stopButton.clicked.connect(self.kill)

    self.runButton.setEnabled(True)
    self.stopButton.setEnabled(False)

def run(self):
    self.runButton.setEnabled(False)
    self.p = subprocess.Popen(sample.exe)

    #self.p.communicate()

    self.stopButton.setEnabled(True)   
    print "Finish running"  #without communicate() it will print out before .exe finish running

def kill(self):
    self.p.kill()
    self.stopButton.setEnabled(False)
    print 'You have stop the program'
    self.runButton.setEnabled(True)

我正在使用 Window7、Python 2.7、pyqt4。我不必使用子进程,任何打开并能够杀死子程序的东西都可以。

提前致谢。

Edit:尝试使用QProcess正如达诺建议的那样。我已将以下代码添加到我的程序中:

def gui(QtCore.Widget):
    self.process = QtCore.QProcess(self)    

def run(self):
    self.process.start(exe_path)
    self.process.started.connect(self.onstart)
    self.process.finished.connect(self.onfinish)
    self.runButton.setEnabled(False)

    #self.p = subprocess.Popen(sample.exe)   #removed
    #self.p.communicate()                    #removed

def onstart (self):
    self.stopButton.setEnabled(True)     
    self.runButton.setEnabled(False)
    print "Started\n"

def onfinish (self):
    self.stopButton.setEnabled(False)     
    self.runButton.setEnabled(True)
    print "Finish running\n"

def kill(self):
    self.process.kill()
    #self.p.kill()                           #removed

这是输出:

点击“运行”(子程序运行结束时输出)

Finish running

第二次点击“运行”

Started

点击“停止”

Finish running
Finish running

第三次单击“运行”

Started
Started

点击“停止”

Finish running
Finish running
Finish running

这里发生了一些事情。


p = subprocess.Popen(exe)不等待exe完成——它会尽快返回exe已开始。

p.communicate()确实等待子进程结束,因此它会阻塞您的 GUI 线程(GUI 冻结直到子进程退出)。

为了避免阻塞 GUI,您可以检查是否p.poll()回报None找出是否p进程仍在运行。通常 GUI 框架提供了一种设置定期回调的方法(例如,Qt 的 QTimer)——您可以调用p.poll()那里。 或者放置阻塞调用(例如p.wait())进入后台线程并在完成时通知 GUI 线程(发出信号,生成事件)。

质量过程由@dano建议 https://stackoverflow.com/questions/28220197/how-to-do-stuff-during-and-after-a-child-process#comment44804834_28220197已经内置了通知机制(finished信号)。

As @三菠萝 说 https://stackoverflow.com/questions/28220197/how-to-do-stuff-during-and-after-a-child-process#comment44814595_28220197:如果您不希望多次调用回调,请不要多次连接同一信号。你的情况没有必要打电话.start()在同一个流程实例上多次:

def run(self):
    self.runButton.setEnabled(False) # call it first because 
                                     # processes are not started instantly
    self.process = QtCore.QProcess(self) 
    self.process.started.connect(self.onstart) # connect "start" signal
    self.process.finished.connect(self.onfinish)
    self.process.start(exe_path, args) # then start
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在子进程期间和之后执行操作 的相关文章

随机推荐

  • Visual Studio 2015 中的 TypeScript、Html 和 JS 文件嵌套

    如何在 Visual Studio 中管理 控制 TypeScript 文件的嵌套 我得到了嵌套和非嵌套文件的混合 我不确定如何 为什么 如下所示 TypeScript 项目中 JavaScript 文件的默认设置是排除它们而不是嵌套它们
  • VHDL FSM多驱动网Q连接到常量驱动程序,其他驱动程序被忽略,我的代码有什么问题?

    这段代码是一个 FSM 它是一个摩尔机 艾莉莎 P 哈克 Alyssa P Hacker 有一只蜗牛 沿着纸带爬下去 上面有 1 和 0 蜗牛 每当最后两个时都会微笑 它爬过的数字是 01 设计摩尔和米利 蜗牛大脑的 FSM 代码如下所示
  • Hibernate错误:org.hibernate.NonUniqueObjectException:具有相同标识符值的不同对象已与会话关联[重复]

    这个问题在这里已经有答案了 可能的重复 Hibernate 具有相同标识符值的不同对象已与会话关联 https stackoverflow com questions 3553200 hibernate different object w
  • 使用 Javascript 播放音频元素 (html5)

    我正在尝试弄清楚如何触发从 javascript 播放音频 我得到了一些 html 看起来像 div class audio foo div
  • 删除 geom_tile 中的空白并匹配 geom_vline&hline 位置

    使用时我无法删除矩形之间的空白geom tile功能 df lt data frame x c seq 2 16 2 seq 17 39 2 y c rep c seq 8 26 2 seq 27 45 2 each 20 z c 1 40
  • Jquery Dialog 打开多个对话框

    我在同一页面上有多个图像 对于每个图像 单击时 我试图打开一个对话框 我在 HTML 设置中设置了以下 6 个图像 当前 当我单击图像时 会弹出 6 个对话框 所有对话框都具有与第一个 div 中找到的相同信息 如何修改我的脚本以使其正常工
  • div 中的文本 - 使用 jQuery 自动滚动 - jsFiddle

    我有以下 HTML 我的小提琴 http jsfiddle net 8yKjD 1 我想要 p 元素及其文本从下到上垂直滚动 我如何在不使用任何插件的情况下使用 jQuery 来做到这一点 提前致谢 http jsfiddle net 8y
  • 实例变量的多态性[重复]

    这个问题在这里已经有答案了 这是我写的三个类 public class Shape public int x 0 public void getArea System out println I don t know my area pub
  • CSS 选择器太长是不是不好?

    选择器是这样的 a b c d e f g h zzzzz font size 16px 对性能不好 如果是 如何 如果否 为什么 我在 Google 上搜索并阅读了很多帖子 包括 Mozilla 的帖子 但没有发现任何提及使用大量类名作为
  • VBA 从 Word 到 Excel

    我在使用 Word 模板中的一些 VBA 代码时遇到问题 目的是让代码打开 Excel 书籍 引用名为 Log 的工作表 并根据 Word 文档的名称查找行 一旦名称匹配 我想将单元格值更改为 已完成 然后保存并关闭 Excel 工作簿 我
  • boost::mpl::fold 用于双参数抽象

    我有一个名为 caRender 的类 它为 clientObjectTypes 中的每个给定对象类型提供一个 caRender renderClientObject 方法 所以下面的代码片段显示了这个运行情况 define UNUSED x
  • 实现多个剪辑路径相交的正确方法是什么?

    As described in another post https stackoverflow com questions 17003171 how to identify which clip paths apply to a path
  • MySQL 清除表中的重复条目并重新链接依赖表中的 FK

    这是我的情况 我有 2 张桌子 patient and study 每个表都有自己的 PK 使用自动增量 就我而言 pat id 应该是唯一的 它没有在数据库级别声明为唯一 因为它在某些用途中可能不是唯一的 它不是自制系统 我找到了如何配置
  • Java 是否提供“friend”访问修饰符?

    我想知道 Java 是否提供了 friend 如 C 中的 访问修饰符 有人说我们可以将 friend 作为 Java 中的默认修饰符 这是真的吗 Java 中的默认访问修饰符允许同一包中的任何代码访问成员
  • 公式中的行根据另一个单元格中的值更改

    我正在尝试在 Excel 中创建一个段落 我在另一张表中列出了我想要从中提取的值 这是我正在使用的代码 CONCATENATE Dear Linkage Log I6 Blah Blah Blah 我希望我的列进行相同的更改 但我试图让 6
  • Delphi XE 和使用 OnKeyDown 捕获箭头键

    我希望我的表单能够处理箭头键 而且我可以做到 只要表单上没有按钮 为什么是这样 关键消息由接收这些消息的控件本身进行处理 这就是为什么当您使用按钮时表单不会接收消息 因此 通常您必须对这些控件进行子类化 但 VCL 足够友好地询问父子表单如
  • 为什么在处理.org java pdf 导出时只显示一个框?

    下面是我的代码 在运行时它显示了我想要的多个框 但是当我尝试导出时 它只在该帧位置显示一个框 我尝试在特定帧生成输出 但它有同样的问题 import processing pdf int ofs 500 boolean record voi
  • 每个域都有唯一的 IP 吗?

    我想知道每个域名地址是否都有唯一的IP地址 此外 这些IP位于哪里 这个重定向系统是如何工作的 当我们尝试通过写入域名来访问网站时 它有多少个重定向 谢谢 否 每个域没有自己的 IP 地址 多个域可以托管在同一台服务器上 并且位于同一 IP
  • 参数类型 Observable 不可分配给 User[] 类型的参数

    我正在努力适应material https material angular io components table overview示例如下 import Component from angular core import MatTab
  • 如何在子进程期间和之后执行操作

    我有一个调用子程序的程序 当子程序使用 Popen 运行时 我需要禁用运行按钮并启用停止按钮 但是 由于Popen打开了一个新进程 因此程序完成后应该打印的内容会立即打印出来 我尝试添加self p communicate after Po