Skip to content

Commit 62040b5

Browse files
committed
执行命令得到结果 #174
1 parent 6dbe593 commit 62040b5

File tree

5 files changed

+138
-0
lines changed

5 files changed

+138
-0
lines changed

QProcess/GetCmdResult.py

+116
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
#!/usr/bin/env python
2+
# -*- coding: utf-8 -*-
3+
"""
4+
Created on 2023/02/01
5+
@author: Irony
6+
@site: https://pyqt.site https://github.com/PyQt5
7+
8+
@file: GetCmdResult.py
9+
@description:
10+
"""
11+
12+
import sys
13+
14+
try:
15+
from PyQt5.QtCore import QProcess
16+
from PyQt5.QtWidgets import (QApplication, QLabel, QPushButton,
17+
QTextBrowser, QVBoxLayout, QWidget)
18+
except ImportError:
19+
from PySide2.QtCore import QProcess
20+
from PySide2.QtWidgets import (QApplication, QLabel, QPushButton,
21+
QTextBrowser, QVBoxLayout, QWidget)
22+
23+
24+
class Window(QWidget):
25+
26+
def __init__(self, *args, **kwargs):
27+
super(Window, self).__init__(*args, **kwargs)
28+
self.setWindowTitle('执行命令得到结果')
29+
layout = QVBoxLayout(self)
30+
layout.addWidget(QLabel('点击执行 ping www.baidu.com', self))
31+
32+
self.buttonRunSync = QPushButton('同步执行', self)
33+
layout.addWidget(self.buttonRunSync)
34+
self.buttonRunSync.clicked.connect(self.run_ping)
35+
36+
self.buttonRunASync = QPushButton('异步执行', self)
37+
layout.addWidget(self.buttonRunASync)
38+
self.buttonRunASync.clicked.connect(self.run_ping)
39+
40+
self.resultView = QTextBrowser(self)
41+
layout.addWidget(self.resultView)
42+
43+
self._pingProcess = None
44+
45+
def run_ping(self):
46+
sender = self.sender() # 同步或者异步按钮
47+
self.buttonRunSync.setEnabled(False)
48+
self.buttonRunASync.setEnabled(False)
49+
50+
if self._pingProcess:
51+
self._pingProcess.terminate()
52+
53+
self._pingProcess = QProcess(self)
54+
self._pingProcess.setProgram('ping')
55+
if sys.platform.startswith('win'):
56+
self._pingProcess.setArguments(['-n', '5', 'www.baidu.com'])
57+
self._pingProcess.setArguments(['-n', '5', 'www.baidu.com'])
58+
elif sys.platform.startswith('darwin') or sys.platform.startswith(
59+
'linux'):
60+
self._pingProcess.setArguments(['-c', '5', 'www.baidu.com'])
61+
# 合并输出流和错误流,执行完毕后通过readAll可以一次性读取所有结果
62+
self._pingProcess.setProcessChannelMode(QProcess.MergedChannels)
63+
self._pingProcess.started.connect(self.on_started)
64+
65+
if sender == self.buttonRunASync:
66+
# 异步执行
67+
self._pingProcess.finished.connect(self.on_finished)
68+
self._pingProcess.errorOccurred.connect(self.on_error)
69+
self._pingProcess.start()
70+
elif sender == self.buttonRunSync:
71+
# 同步执行
72+
self._pingProcess.start()
73+
if self._pingProcess.waitForFinished():
74+
self.on_finished(self._pingProcess.exitCode(),
75+
self._pingProcess.exitStatus())
76+
else:
77+
self.resultView.append('ping process read timeout')
78+
self.on_error(self._pingProcess.error())
79+
80+
def on_started(self):
81+
self.resultView.append('ping process started')
82+
83+
def on_finished(self, exitCode, exitStatus):
84+
self.resultView.append(
85+
'ping process finished, exitCode: %s, exitStatus: %s' %
86+
(exitCode, exitStatus))
87+
# 读取所有结果
88+
result = self._pingProcess.readAll().data()
89+
try:
90+
import chardet
91+
encoding = chardet.detect(result)
92+
self.resultView.append(result.decode(encoding['encoding']))
93+
except Exception:
94+
self.resultView.append(result.decode('utf-8', errors='ignore'))
95+
self._pingProcess.kill()
96+
self._pingProcess = None
97+
self.buttonRunSync.setEnabled(True)
98+
self.buttonRunASync.setEnabled(True)
99+
100+
def on_error(self, error):
101+
self.resultView.append('ping process error: %s, message: %s' %
102+
(error, self._pingProcess.errorString()))
103+
self._pingProcess.kill()
104+
self._pingProcess = None
105+
self.buttonRunSync.setEnabled(True)
106+
self.buttonRunASync.setEnabled(True)
107+
108+
109+
if __name__ == '__main__':
110+
import cgitb
111+
112+
cgitb.enable(format='text')
113+
app = QApplication(sys.argv)
114+
w = Window()
115+
w.show()
116+
sys.exit(app.exec_())

QProcess/README.en.md

Whitespace-only changes.

QProcess/README.md

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# QProcess
2+
3+
- 目录
4+
- [执行命令得到结果](#1执行命令得到结果)
5+
6+
## 1、执行命令得到结果
7+
[运行 GetCmdResult.py](GetCmdResult.py)
8+
9+
`QProcess` 常用执行命令方式有以下几种:
10+
1. `QProcess.execute('ping', ['www.baidu.com'])`:同步执行,返回值为进程退出码
11+
2. `QProcess.startDetached('ping', ['www.baidu.com'], '工作路径')`:返回值为是否启动成功,该命令一般用于启动某个程序后就不管了
12+
3. 通过构造`QProcess`对象,然后通过`QProcess.start()`启动进程,并分为同步和异步两种方式获取输出
13+
14+
示例代码为第3种方式:
15+
16+
1. 通过`setProcessChannelMode(QProcess.MergedChannels)`合并标准输出和错误输出
17+
2. `waitForFinished`为同步方式,然后调用`readAll`读取所有输出
18+
3. 也可以绑定`finished`信号,然后通过`readAll`读取所有输出
19+
20+
![GetCmdResult](ScreenShot/GetCmdResult.gif)

QProcess/ScreenShot/GetCmdResult.gif

100 KB
Loading

README.md

+2
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,8 @@
240240
- [分割窗口的分割条重绘](QSplitter/RewriteHandle.py)
241241
- [QSerialPort](QSerialPort)
242242
- [串口调试小助手](QSerialPort/SerialDebugAssistant.py)
243+
- [QProcess](QProcess)
244+
- [执行命令得到结果](QProcess/GetCmdResult.py)
243245
- [QProxyStyle](QProxyStyle)
244246
- [Tab文字方向](QProxyStyle/TabTextDirection.py)
245247
- [Tab角落控件位置占满](QProxyStyle/TabCornerWidget.py)

0 commit comments

Comments
 (0)