PyQT5 GUI中内置CMD

PyQt实现了一个Python模块集。它有超过300类,将近6000个函数和方法。它是一个多平台的工具包,可以运行在所有主要操作系统上,包括UNIX,Windows和Mac。 PyQt采用双许可证,开发人员可以选择GPL和商业许可。在此之前,GPL的版本只能用在Unix上,从PyQt的版本4开始,GPL许可证可用于所有支持的平台。

qt

直接在QT中内置CMD

在PyQT5下,将CMD应用直接内置到窗体应用中去:

qt1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
import sys
import subprocess
import time
import win32gui

from PyQt5.QtCore import QProcess, Qt
from PyQt5.QtGui import QWindow, QIcon, QFont
from PyQt5.QtWidgets import QMainWindow
from PyQt5.QtWidgets import QMdiArea, QSplitter, QTextBrowser
from PyQt5.QtWidgets import QWidget, QApplication, QVBoxLayout
from win32com import client
from win32gui import GetWindowText, EnumWindows,SetForegroundWindow
class Example(QMainWindow):

def __init__(self):
super().__init__()
self.p = QProcess()
self.layout = QVBoxLayout()
self.mdi = QMdiArea()
self.mainSplitter = QSplitter(Qt.Vertical)
self.setCentralWidget(self.mainSplitter)
self.mainSplitter.addWidget(QTextBrowser())
self.initUI()

def initUI(self):
self.runExe()
EnumWindows(self.set_cmd_to_foreground, None)
hwnd1 = win32gui.GetForegroundWindow()
#hwnd1 = win32gui.FindWindow(None, "C:\\Windows\\system32\\calc.exe")
print(hwnd1)
window = QWindow.fromWinId(hwnd1)
container_widge = self.createWindowContainer(window, self)
container_widge.setFocusPolicy(Qt.TabFocus)
container_widge.setFocus()
container_widge.setWindowTitle("ain")
container_widge.setFont(QFont("Times New Roman"))
container_widge.setGeometry(500, 500, 450, 400)
#container_widge.setFocusPolicy()
container_widge.activateWindow()
container_widge.acceptDrops()
container_widge.grabMouse()
container_widge.setMouseTracking(True)
self.mainSplitter.addWidget(container_widge)
self.showMaximized()
#self.setGeometry(200, 200, 700, 700)
#self.show()
def runExe(self):
shell.run("cmd.exe")
time.sleep(1)
def set_cmd_to_foreground(self, hwnd, extra):
"""sets first command prompt to forgeround"""
if "cmd.exe" in GetWindowText(hwnd):
print(hwnd)
SetForegroundWindow(hwnd)
return
def run_script(self, shell, scripts):
"""runs the py script"""
shell.SendKeys(scripts+"{ENTER}")
if __name__ == '__main__':
shell = client.Dispatch("WScript.Shell")
app = QApplication(sys.argv)
ex = Example()
#ex.run_script(shell, "python -m pip list")
#ex.show()
sys.exit(app.exec_())

将CMD命令结果返回到QT

qt2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
import sys  

from PyQt5.QtCore import QProcess, QTextStream
from PyQt5.QtWidgets import QApplication, QMainWindow, QTextEdit, QLineEdit, QVBoxLayout, QHBoxLayout, QWidget, \
QPushButton


class MainWindow(QMainWindow):
def __init__(self):
super().__init__()

self.process = QProcess(self)
self.output = QTextEdit(self)
self.input = QLineEdit(self)
self.run_command_button = QPushButton("Run Command", self)

layout = QVBoxLayout()
input_layout = QHBoxLayout()
input_layout.addWidget(self.input)
input_layout.addWidget(self.run_command_button)
layout.addLayout(input_layout)
layout.addWidget(self.output)
central_widget = QWidget(self)
central_widget.setLayout(layout)
self.setCentralWidget(central_widget)

self.process.readyReadStandardOutput.connect(self.read_output)
self.run_command_button.clicked.connect(self.run_command)
self.process.start("cmd.exe")

def read_output(self):
stream = QTextStream(self.process)
self.output.append(stream.readAll())

def run_command(self):
command = self.input.text() + "\n"
self.process.write(command.encode())


if __name__ == '__main__':
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())

QT QProcess调用py文件,使用readyReadStandardOutput()无法获得信号的解决办法:

1
2
# 解决办法是在py文件的每一行print()后面添加一行代码
sys.stdout.flush()

因为python中print()一次并不是立即打印,而是要等缓冲区满了再打印,用这种办法强制刷新缓冲区后,可以立即触发信号。


PyQT5 GUI中内置CMD
https://skynetboys.github.io/2023/09/26/PyQT5-GUI中内置CMD/
Author
Edison
Posted on
September 26, 2023
Licensed under