我想问一下如何从磁盘读取一个大文件并保持PyQt4 UI响应(未阻止)。我已经将文件的负载移动到QThread子类,但我的GUI线程被冻结了。有什么建议?我认为它必须与GIL有关,但我不知道如何对它进行排序?
编辑: 我正在使用GDCM项目中的vtkGDCMImageReader来读取多帧DICOM图像并使用vtk和pyqt4显示它。我在另一个线程(QThread)中加载,但我的应用程序冻结,直到图像加载。这是一个示例代码:
class ReadThread(QThread):
def __init__(self, file_name):
super(ReadThread, self).__init__(self)
self.file_name = file_name
self.reader.vtkgdcm.vtkGDCMImageReader()
def run(self):
self.reader.SetFileName(self.file_name)
self.reader.Update()
self.emit(QtCore.SIGNAL('image_loaded'), self.reader.GetOutput())
答案 0 :(得分:3)
我猜你正在直接调用run
来开始这个帖子。这会使GUI冻结,因为你没有激活线程。
所以你错过了那里的start
,这会间接地正确地调用run
:
thread = ReadThread()
thread.begin()
class ReadThread(QThread):
def __init__(self, file_name):
super(ReadThread, self).__init__(self)
self.file_name = file_name
self.reader.vtkgdcm.vtkGDCMImageReader()
def run(self):
self.reader.SetFileName(self.file_name)
self.reader.Update()
self.emit(QtCore.SIGNAL('image_loaded'), self.reader.GetOutput())
def begin(self):
self.start()
答案 1 :(得分:2)
有点晚了,但我想我可以找出你面临的问题。
图像很大,解压缩可能是CPU密集型任务。这意味着您的GUI线程进入休眠状态,加载线程受CPU限制。此时加载线程具有GIL,GUI无法启动。
即使您可以进入加载线程并引入睡眠(0),以使GUI继续运行,这对于多核处理器或多处理器机器也无济于事。发生的事情是O / S有两个线程,并认为它可以同时运行。加载线程设置在(例如)核心1上,GUI可以加载并运行(例如)核心2.因此,在核心2上启动加载并启动GUI线程后,O / S恢复加载线程在核心1 - 它突然抓住了GIL。片刻之后,GUI线程就可以开始了,并尝试获取失败的GIL。没有GIL它可以做的就是回去睡觉!
一种解决方案是以策略间隔在后台线程中插入一个短(大于零)睡眠,以便GUI可以运行。这并不总是可行的。
答案 2 :(得分:1)
答案 3 :(得分:0)
也许在步骤中创建您的读者对象:
class ReadThread(QThread):
def __init__(self, file_name):
super(ReadThread, self).__init__(self)
self.file_name = file_name
- self.reader = vtkgdcm.vtkGDCMImageReader()
def run(self):
+ self.reader = vtkgdcm.vtkGDCMImageReader()
self.reader.SetFileName(self.file_name)
self.reader.Update()
self.emit(QtCore.SIGNAL('image_loaded'), self.reader.GetOutput())