最近我问了question关于如何使用嵌套循环生成运行多个QProcess实例时如何防止QThread冻结GUI的问题。提供的解决方案就像魅力一样!我能够完成我的程序,并且运行顺利!我最近添加了一项功能,允许用户在此过程中的任何时候停止QThread。停止功能的工作原理是不会调用新的QProcesse实例。但是,仍有许多未完成的QProcess实例仍在处理中。有没有一种方法可以确定何时不再有任何QProcess实例正在运行并通知用户?我熟悉QProcess方法waitForFinished(),但是我不确定如何将其应用于使用嵌套循环生成的QProcess的多个实例。
这里是模拟我实际程序的数据处理方面的代码示例:
# This Python file uses the following encoding: utf-8
import sys
import os
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
import test
import time
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.ui=test.Ui_test()
self.ui.setupUi(self)
self.ui.pushButton_startThread.clicked.connect(self.startTestThread)
self.ui.pushButton_Update.clicked.connect(self.stopThread)
def startTestThread(self):
self.xValue = self.ui.lineEdit_x.text() #Represents number of batches
self.yValue = self.ui.lineEdit_y.text() #Represents number of images per batch
self.runTest = testThread(self.xValue, self.yValue, self) # Creates an instance of testThread
self.runTest.start() # Starts the instance of testThread
def stopThread(self):
self.runTest.stop()
self.ui.lineEdit_x.setText("")
self.ui.lineEdit_y.setText("")
class testThread(QThread):
def __init__(self, xValue, yValue, parent=None):
super().__init__(parent)
self.xValue = xValue
self.yValue = yValue
def __del__(self):
self.wait()
def run(self):
processd = []
for x in range(int(self.xValue)): # For loop to iterate througeach batch
pass
for y in range(
int(self.yValue)): # For loop to iterate through each image in each batch
time.sleep(.1)
QProcess.startDetached(os.path.dirname(os.path.realpath(__file__)) + r"\test.bat") # Runs test.bat
def stop(self):
self.terminate()
self.wait()
print("\nStopping thread")
if __name__ == "__main__":
app = QApplication(sys.argv)
app.setStyle("Fusion")
window = MainWindow()
window.show()
sys.exit(app.exec_())
test.bat
@ECHO OFF
ECHO Processing Batched Images.
TIMEOUT /T 15
ECHO Process Finished.
如前所述,停止QThread工作;但是,我希望能够确定何时完成所有QProcess实例。这将允许程序通知用户他们可以使用新参数重新启动过程。目前,我不得不告诉我的同事们等到不再写入任何输出文件,然后再尝试一组新的参数。
任何帮助将不胜感激。谢谢您的时间!
虽然不是很优雅,但我想出了一种方法来确定终止QThread之后何时完成QProcess的多个实例:
这里是代码示例:
# This Python file uses the following encoding: utf-8
import sys
import os
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
import test
import time
from glob import glob1
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.ui=test.Ui_test()
self.ui.setupUi(self)
self.ui.pushButton_startThread.clicked.connect(self.startTestThread)
self.ui.pushButton_Update.clicked.connect(self.stopThread)
def startTestThread(self):
self.xValue = self.ui.lineEdit_x.text() #Represents number of batches
self.yValue = self.ui.lineEdit_y.text() #Represents number of images per batch
self.runTest = testThread(self.xValue, self.yValue, self) # Creates an instance of testThread
self.runTest.signals.batchesSubmitted.connect(self.testThreadFinished)
self.runTest.start() # Starts the instance of testThread
def stopThread(self):
self.runTest.stop()
@pyqtSlot(int)
def testThreadFinished(self, batchesSubmitted):
while len(glob1(outputFilePath + fileName, "*.txt")) < batchesSubmitted: #Compare the number of *.txt files in the output directory to the number of isntances of QProcess called
time.sleep(1)
self.ui.lineEdit_x.setText("")
self.ui.lineEdit_y.setText("")
print("All instance of QProcess are finished!")
class testThreadSignals(QObject):
batchesSubmitted = pyqtSignal(int)
class testThread(QThread):
def __init__(self, xValue, yValue, parent=None):
super().__init__(parent)
self.xValue = xValue
self.yValue = yValue
self.signals = testThreadSignals()
def run(self):
self.batchCounter = 0
for x in range(int(self.xValue)): # For loop to iterate througeach batch
pass
for y in range(
int(self.yValue)): # For loop to iterate through each image in each batch
time.sleep(.1)
QProcess.startDetached(os.path.dirname(os.path.realpath(__file__)) + r"\test.bat") # Runs test.bat
self.batchCounter += 1 #Counts the successful number *.txt files written
@pyqtSlot(int)
def stop(self):
self.terminate()
self.threadactive = False
self.wait()
self.signals.batchesSubmitted.emit(self.batchCounter)
if __name__ == "__main__":
app = QApplication(sys.argv)
app.setStyle("Fusion")
window = MainWindow()
window.show()
sys.exit(app.exec_())
test.bat:
@ECHO OFF
ECHO Processing Batched Images.
TIMEOUT /T 15
REM write a unique text file
ECHO Process Finished.
我能够将上面的python代码毫无问题地适应我的程序。