现在使用得 PYQT5 做的做了一个 GUI 界面,在这个 GUI.py 文件里面 print 打印得信息已经让我重定向到了文本框中,有一个问题,我在调用其他 py 文件的时候(这个 py 文件也有 print 打印信息),无法打印到 GUI 界面下的文本框中,而是打印到了 pycharm 得控制台,有谁能帮我想想思路怎么做可以?
我是通过 os.system(“ python +py 文件”) 调用得。
1
ysc3839 2018-08-17 18:50:51 +08:00 via Android
用管道重定向其他进程的 stdout ?
|
2
jiangwb 2018-08-17 19:00:44 +08:00
是的,输出重定向就可以了。
|
3
Droi 2018-08-17 20:04:57 +08:00
用 QProcess()
http://doc.qt.io/qt-5/qprocess.html#readAllStandardOutput ```python p = QProcess() p.setProcessChannelMode(QProcess.MergedChannels) p.setProcessEnvironment(QProcessEnvironment.systemEnvironment()) p.readyRead.connect(GUIoutput) p.start(“ python +py 文件”, QIODevice.ReadWrite) def GUIoutput(): TextEdit.moveCursor(QTextCursor.End) outputTextEdit.insertPlainText( str(p.readAllStandardOutput(), "utf-8")) TextEdit.moveCursor(QTextCursor.End) ``` 具体自己修改下,代码流程是这样的。 |
4
iismark2018 OP @Droi 好的,我试试周一的时候,谢谢!
|
5
iismark2018 OP @jiangwb 主要已经做了重定向,在当前的 py 代码里面 print 可以直接打印到文本框里面,但是调用其他的 py 文件,这个 py 文件 print 的信息不会打印。
|
6
iismark2018 OP @Droi 尝试了一下,文本框无法打印想要输出的内容,因为执行的是线程,然后在这个线程下面 用重定向不好使。
|
7
iismark2018 OP 贴一下源码
import time from comm.atc import atLogger, atChat import subprocess import sys import os import time import datetime import requests import json import random from PyQt5.QtWidgets import (QApplication,QWidget,QLabel,QAction,QProgressBar, QPushButton,QMainWindow,QTextEdit,QGridLayout,QComboBox) from PyQt5.QtGui import QIcon,QTextCursor from PyQt5.QtCore import QThread,pyqtSignal,QCoreApplication,QObject,QBasicTimer,Qt,QProcess,QProcessEnvironment,QIODevice from comm.at import COMPORT class ThreadAp(QThread): name = """操作 AP 控制""" apstatus = pyqtSignal() def run(self): # url = "http://192.168.104.1/" # s = requests.session() # header ={ # "token":"Ku2vhFFTc9K5V%24Laf2l2V9I%24PqX%249I", # "Accept-Encoding": "gzip, deflate", # "Accept-Language": "zh-CN, zh;q=0.9", # "Referer": "http://192.168.104.1/", # "User-Agent":"Mozilla/5.0(Windows NT10.0; Win64; x64) AppleWebKit/537.36 (KHTML,like Gecko) Chrome/67.0.3396.62 Safari/537.36", # } # login = {"method":"do","login":{"password":"0KcgeXhc9TefbwK"}} # response = requests.post(url,data=json.dumps(login),headers=header).text # jsonload = json.loads(response) # stok = jsonload["stok"] # print(stok) # setwlanurl = "http://192.168.104.1/stok=%s/ds"%stok # channelnum = {"method":"set","wireless":{"wlan_host_2g":{"channel":"1", "mode": "3"}}} # channelnum2 ={"method":"set","wireless":{"wlan_host_2g":{"channel":"11","mode":"1","bandwidth":"1"}}} # channerlpost = requests.post(setwlanurl, data=json.dumps(channelnum)) # print(channerlpost.text) script = os.getcwd() + r'\network\Network_01.py' # 获取当前路径拼接 Network_01 所在位置 cmd = 'python ' + '-m unittest '+script # python +py 所在地址 # r = os.system(cmd) # 执行 runTest.py 文件 r =subprocess.Popen(cmd,shell=True) -----------------------------------------------------在这个下面加------------------------------------------------------------------- class ThreadQt(QThread): name = """AT 命令测试线程""" status = pyqtSignal() #实例化一个无参数信号 steps = pyqtSignal(int) #实例化一个 int 参数信号 times = 2 #设置测试次数参数 def run(self): for i in range(0, self.times): n = i + 1 print("------------Test Round : %s on %s------------" % (str(n), COMPORT)) print("--------------------V1.1 测试版------------------") print("---------------------" + datetime.datetime.fromtimestamp(time.time()).strftime( "%Y-%m-%d-%H-%M-%S") + "------------------") time.sleep(0.2) script = os.getcwd() + r'\runTest.py' #获取当前路径拼接 runTest 所在位置 cmd = 'python ' + script #python +py 所在地址 os.system(cmd) #执行 runTest.py 文件 time.sleep(1) #休眠 1 秒 print("-----------------------第%s 遍测试已完成--------------------"%n) print("\n") step = n*(100/self.times) #计算百分比 self.steps.emit(step) #发射 step 信号给进度条槽 try: os.system('python '+os.getcwd()+r'\config\SendMail.py')#获取当前路径拼接 SendMail 所在位置 print("邮件发送成功") except: print("Error: 无法发送邮件") time.sleep(0.5) print("*****自动化全部测试完毕,请查看 result 文件下的 Html 报告*****") self.status.emit()#发射 step 信号给开始测试 slotStart 槽 class EmittingStream(QObject): textWritten = pyqtSignal(str) #实例化一个 str 参数信号 def write(self, text): self.textWritten.emit(str(text))#发射一个 str 参数信号给 normalOutputWritten 槽 class MainWindow(QMainWindow): name = """主界面""" def __init__(self): super().__init__() self.title = "" #初始化界面工具名称 self.left = 300 self.top = 300 self.width = 750 self.height = 500 self.imge = '' #初始化界面工具图标 self.initUI() def initUI(self): self.setWindowTitle(self.title) #设置 GUI 界面名称 self.setGeometry(self.left, self.top, self.width, self.height) #设置 GUI 界面大小 self.setWindowIcon(QIcon(self.imge)) #设置 GUI 界面图标 self.textedit = QTextEdit(self) #添加一个 text 文本框 self.textedit.move(300, 50) self.textedit.resize(400, 350) self.textedit.setObjectName("textedit") #设置一个 text 文本框名字 self.textedit.setReadOnly(True) #设置文本框只读模式 self.settingAction = QAction(QIcon(), '&DUT 串口参数', self) #添加一个菜单栏属性 self.versionAction = QAction(QIcon(), '&联盛德发布\n' 'V1.1 测试版', self) #添加一个菜单栏属性 self.Secondwindow = Secondwindow() #实例化第二个 GUI 界面对象 self.settingAction.triggered.connect(self.Secondwindow.show) #这是点击串口参数弹出另一个 GUI 界面 mainMenu = self.menuBar() fileMenu = mainMenu.addMenu('设置') #添加一个菜单栏 viewMenu = mainMenu.addMenu('版本') fileMenu.addAction(self.settingAction) viewMenu.addAction(self.versionAction) self.button = QPushButton('AT 测试', self) #添加一个开始测试按钮 self.button.move(50, 70) self.exitbu = QPushButton('退出', self) #添加一个退出按钮 self.exitbu.move(90, 350) self.button2 = QPushButton('加网测试', self) #添加一个开始测试按钮 self.button2.move(170, 70) self.exitbu.clicked.connect(QCoreApplication.instance().quit) #为退出按钮链接退出快捷功能 self.thread = ThreadQt() #实例化 ThreadQt 线程对象 self.threadAP = ThreadAp() #实例化 ThreadAp 线程对象 self.button.clicked.connect(self.slotStart) self.button2.clicked.connect(self.startAp) self.thread.status.connect(self.slotEnd) self.thread.steps.connect(self.doAction) self.threadAP.apstatus.connect(self.endAp) self.pbar = QProgressBar(self) self.pbar.setGeometry(50, 450, 700, 25) # 从左上角 30-50 的界面,显示一个 200*25 的界面 self.setWindowFlags(Qt.WindowMinimizeButtonHint) # 禁止最大化 sys.stdout = EmittingStream(textWritten=self.normalOutputWritten)# 重定向输出 sys.stderr = EmittingStream(textWritten=self.normalOutputWritten) def slotStart(self): try: os.remove(os.getcwd()+r'\config\time.txt') except: pass self.pbar.setValue(0) self.button.setText("自动化测试中") self.button.setEnabled(False) self.thread.start() def slotEnd(self): self.button.setText("测试") self.button.setEnabled(True) def doAction(self,steps): self.pbar.setValue(steps) def startAp(self): self.pbar.setValue(0) self.button2.setText("自动化测试中") self.button2.setEnabled(False) self.threadAP.start() # try: # self.threadmail.start() # except: # pass def endAp(self): self.button2.setText("测试") self.button2.setEnabled(True) def __del__(self): sys.stdout = sys.__stdout__ sys.stderr = sys.__stderr__ def normalOutputWritten(self, text): cursor = self.textedit.textCursor() cursor.movePosition(QTextCursor.End) cursor.insertText(text) self.textedit.setTextCursor(cursor) self.textedit.ensureCursorVisible() def main(): app = QApplication(sys.argv) win = MainWindow() win.show() sys.exit(app.exec_()) if __name__ == '__main__': main() |
8
Droi 2018-08-20 15:20:13 +08:00
用 os.system 启动程序。程序输出数据都丢到 sys.stdout。怎么拿出来动态存在一个变量,不太清楚。
用 r=subprocess.Popen 可以用 r.communicate()拿数据。 你可以先写小脚本,再慢慢改。 |
9
iismark2018 OP @Droi 嗯嗯,用 os.popen()获取到内容,我需要 read 一下然后打印出来,这样能实现但是就不是实时同步了,等待测试执行完毕后,可以打印出信息。
|
10
frostming 2018-08-21 10:45:24 +08:00 1
@iismark2018 谁说不能实时了?
fp = os.popen('run script') for line in iter(fp.readline, ''): print(line, end='') 按行输出 |
11
iismark2018 OP @frostming fp = os.popen(cmd) rd = fp.readlines() for i in rd: print(i) 我是这样的不实时,感谢大佬 为小弟解了难题,爱你么么!!!
|