最近做了个项目,需要用PyQt5编写一个exe程序,并且调用客户的接口是exe形式的
开始用python自带的subprocess.Popen()调用客户的exe,run和debug都可以执行;但是打包后,调用客户的exe时,程序就崩溃了,最后定位到是subprocess.Popen()导致崩溃。
想了下,前面使用多线程时,Python和PyQt都有自己的线程方法,使用Python的Thread时,经常出些小问题,使用QtCore.QThread时,就没有;类比思维,会不会PyQt也有自己调用exe的方法呢?果然有:QtCore.QProcess()
网上查了下,主要使用QProcess.start(’***.exe‘)启动exe,但是获取到外部exe返回的数据这个问题一直没弄明白;查了好多资料,大致理解是:获取外部exe返回的数据,接口是QProcess.readAllStandardOutput(),但是是以信号的形式发出的,所以需要将信号关联到自己的函数,来获取返回的数据
def USBID(self):
self.textBrowser_logWindow.clear()
self.label_USBID_Result.clear()
self.label_USBID_Result.setStyleSheet("background-color:yellow")
self.EVKNum = self.comboBox_USBID_Num.currentText()
self.USBIDCmd =os.getcwd() + "\\EvkMonitor.exe -download_usb_id " + str(self.EVKNum) + " -gui off -button down"
self.process = QtCore.QProcess()
self.process.start(self.USBIDCmd)
self.process.readyReadStandardOutput.connect(lambda :self.read_result(str(self.process.readAllStandardOutput().data().decode('utf-8'))))
self.process.finished.connect(lambda :self.finished_exe())
这里self.USBIDCmd是cmd命令,后面带有参数传给exe,这里的lamda:是干什么用的,我不太清除,参考的链接:
self.read_result(str)是处理读到的返回数据:
def read_result(self,nextline):
self.nextline = nextline
if (str(self.nextline).find('Write USB ID Success') != -1):
self.label_USBID_Result.setText('√')
self.label_USBID_Result.setStyleSheet("background-color:green")
self.textBrowser_logWindow.append(str(self.nextline))
self.cursor = self.textBrowser_logWindow.textCursor()
self.textBrowser_logWindow.moveCursor(self.cursor.End)
QApplication.processEvents()
后面我关联了一个监视exe是否运行完的信号函数self.finished_exe():
def finished_exe(self):
if (self.label_USBID_Result.text() != '√'):
self.label_USBID_Result.setText('×')
self.label_USBID_Result.setStyleSheet("background-color:red")
最后再pyinstaller打包,运行,ok,搞定收工