我正在编写一个数据采集程序,我有兴趣始终保持GUI响应。这就是为什么我使用QThreads来完成这项工作。尽管与在单个线程中完成整个作业的情况相比,结果稍微好一些,但我的GUI仍然会挂起,直到任务完成。这是代码的相关部分:
import numpy as np
from PyQt4 import QtGui, QtCore
import h5py as hdf
import tifffile as tiff
class MyWidget(QtGui.QFrame):
def __init__(self, *args, **kwargs):
super(MyWidget, self).__init__(*args, **kwargs)
self.convertButton = QtGui.QPushButton('Convert to TIFF')
self.convertButton.clicked.connect(self.convertToTiff)
recGrid = QtGui.QGridLayout()
self.setLayout(recGrid)
recGrid.addWidget(self.convertButton, 0, 0)
def convertToTiff(self):
self.converterThread = QtCore.QThread()
self.converter = TiffConverter(self.savename, self.dataname)
self.converter.moveToThread(self.converterThread)
self.converterThread.started.connect(self.converter.run)
self.converterThread.start()
class TiffConverter(QtCore.QObject):
def __init__(self, filename, dataname, *args, **kwargs):
super(TiffConverter, self).__init__(*args, **kwargs)
self.filename = filename
self.dataname = dataname
self.file = hdf.File(self.filename, mode='r')
def run(self):
tiff.imsave(self.filename, self.file[self.dataname])
self.file.close()
if __name__ == '__main__':
app = QtGui.QApplication([])
win = MyWidget()
win.show()
app.exec_()
我知道GUI挂起tiff.imsave(self.filename, self.file[self.dataname])
,我很熟悉QThreads并没有真正做并行计算的事实。这可能是GUI挂起的原因吗?或者像我这样分享变量有问题吗?对于这类案件有没有解决办法?
答案 0 :(得分:-1)
您可以使用线程解决问题。
您可以将图像写入功能放在新线程中,然后该任务将独立于UI部分,因此不会滞后。
我已经做好了,如果您需要任何进一步的帮助,请告诉我。
class ThreadLiveViewProcessing(QThread):
def __init__(self):
super(ThreadLiveViewProcessing, self).__init__()
self.is_ThreadLiveViewProcessing_running = True
def run(self):
enter code here
然后,您可以在UI类的init中创建其实例。
class MyWidget(QtGui.QFrame):
def __init__(self, *args, **kwargs):
super(MyWidget, self).__init__(*args, **kwargs)
# Thread should never have parents.
# Create instance of Thread Class for processing in faceme.
self.thread_live_view_processing = ThreadLiveViewProcessing()
self.thread_live_view_processing.start()
... snippet ... code ... etc.
recGrid = QtGui.QGridLayout()
self.setLayout(recGrid)
recGrid.addWidget(self.convertButton, 0, 0)
您可以通过以下方式在需要的地方启动线程:
self.thread_live_view_processing.start()