python代码运行出来是process_python-从用作进度监视器的QDialog中启动QProcess

这是一个示例,您可以如何做(我使用QWidget,但您也可以使用QDialog或其他方法).我不使用单独的线程,因为UI不需要是交互式的.如果要添加按钮等,则应考虑使用运行Qt提供的QObject模型的旧QThread.

#!/usr/bin/python

from PyQt4.QtGui import *

from PyQt4.QtCore import *

import sys

class MyQProcess(QWidget):

def __init__(self):

super(QWidget, self).__init__()

# Add the UI components (here we use a QTextEdit to display the stdout from the process)

layout = QVBoxLayout()

self.edit = QTextEdit()

self.edit.setWindowTitle("QTextEdit Standard Output Redirection")

layout.addWidget(self.edit)

self.setLayout(layout)

# Add the process and start it

self.process = QProcess()

self.setupProcess()

# Show the widget

self.show()

def setupProcess(self):

# Set the channels

self.process.setProcessChannelMode(QProcess.MergedChannels)

# Connect the signal readyReadStandardOutput to the slot of the widget

self.process.readyReadStandardOutput.connect(self.readStdOutput)

# Run the process with a given command

self.process.start("df -h")

def __del__(self):

# If QApplication is closed attempt to kill the process

self.process.terminate()

# Wait for Xms and then elevate the situation to terminate

if not self.process.waitForFinished(10000):

self.process.kill()

@pyqtSlot()

def readStdOutput(self):

# Every time the process has something to output we attach it to the QTextEdit

self.edit.append(QString(self.process.readAllStandardOutput()))

def main():

app = QApplication(sys.argv)

w = MyQProcess()

return app.exec_()

if __name__ == '__main__':

main()

请注意,我正在使用的命令(df -h)运行一次(这是一个Linux命令,显示硬盘上的磁盘使用情况),然后结束了.您也可以将其替换为可以无限期运行的Execute.exe.我已经使用htop(基于终端的高级任务管理器)对其进行了测试,该应用程序一旦启动就不会停止,除非用户希望它停止或系统停止(崩溃,关机等).

请注意,您必须确保以干净的方式停止外部进程.这可以在__del __(析构函数)中执行,也可以在给定窗口小部件寿命结束时调用的另一个函数中完成.我所做的基本上是将SIGTERM(终止)发送到外部进程,并且在经过给定时间后,但该进程仍在运行,我将情况提升为SIGKILL(杀死).

代码显然需要更多的工作,但足以让您了解事情的工作原理.

这是上面代码的相同版本,但有一个额外的线程.请注意,我将输出从外部进程重定向到我的工作器中的插槽.除非您想在该输出上工作,否则不必这样做.因此,您可以跳过此步骤,并将过程信号连接到小部件上的插槽,该插槽将其接收并输出其内容.输出的处理将在单独的线程中再次完成,因此您可以保持距离而不是冻结UI(如果遵循

from PyQt4.QtGui import *

from PyQt4.QtCore import *

import sys

class Worker(QObject):

sendOutput = pyqtSignal(QString)

def __init__(self):

super(Worker, self).__init__()

self.process = QProcess()

self.setupProcess()

def __del__(self):

self.process.terminate()

if not self.process.waitForFinished(10000):

self.process.kill()

def setupProcess(self):

self.process.setProcessChannelMode(QProcess.MergedChannels)

self.process.readyReadStandardOutput.connect(self.readStdOutput)

self.process.start("htop")

@pyqtSlot()

def readStdOutput(self):

output = QString(self.process.readAllStandardOutput())

# Do some extra processing of the output here if required

# ...

self.sendOutput.emit(output)

class MyQProcess(QWidget):

def __init__(self):

super(QWidget, self).__init__()

layout = QVBoxLayout()

self.edit = QTextEdit()

self.thread = QThread()

self.setupConnections()

self.edit.setWindowTitle("QTextEdit Standard Output Redirection")

layout.addWidget(self.edit)

self.setLayout(layout)

self.show()

def setupConnections(self):

self.worker = Worker()

self.thread.finished.connect(self.worker.deleteLater)

self.worker.sendOutput.connect(self.showOutput)

self.worker.moveToThread(self.thread)

self.thread.start()

def __del__(self):

if self.thread.isRunning():

self.thread.quit()

# Do some extra checking if thread has finished or not here if you want to

#Define Slot Here

@pyqtSlot(QString)

def showOutput(self, output):

#self.edit.clear()

self.edit.append(output)

def main():

app = QApplication(sys.argv)

w = MyQProcess()

return app.exec_()

if __name__ == '__main__':

main()

进一步澄清:

正如我在他的答案的评论部分中告诉@BrendanAbel的那样,将插槽与QThread一起使用时存在的问题是,插槽与QThread实例本身具有相同的线程亲和力(=它们属于的线程),即QThread是从创建的.关于QThread,唯一的-我重复唯一的-在单独的线程中运行的是它的事件循环,由QThread.run()表示.如果您在Internet上浏览,您会发现不建议采用这种方式(除非您真的非常了解必须继承QThread),因为自从Qt 4的早期版本run()是抽象的以来,您就必须继承使用QThread才能使用QThread.后来抽象的run()得到了具体的实现,因此消除了对QThread进行子类化的需要.关于线程安全并发出@BrendanAbel所写的内容只是部分正确.它归结为连接类型(默认为自动连接).如果您手动指定连接类型,则实际上可能会使信号不安全.在Qt documentation中了解有关此内容的更多信息.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值