Python PyQt4、QThread和在不冻结GUI的情况下打开大文件
我想问一下如何从磁盘读取一个大文件,并保持PyQt4 UI的响应性(未被阻止)。我已经将文件的加载移到了QThread子类,但是我的GUI线程被冻结了。有什么建议吗?我想这一定是吉尔的问题,但我不知道如何分类 编辑: 我正在使用GDCM项目中的vtkGDCMImageReader读取多帧DICOM图像,并使用vtk和pyqt4显示它。我在另一个线程(QThread)中执行此加载,但在加载图像之前,我的应用程序将冻结。下面是一个示例代码:Python PyQt4、QThread和在不冻结GUI的情况下打开大文件,python,pyqt,Python,Pyqt,我想问一下如何从磁盘读取一个大文件,并保持PyQt4 UI的响应性(未被阻止)。我已经将文件的加载移到了QThread子类,但是我的GUI线程被冻结了。有什么建议吗?我想这一定是吉尔的问题,但我不知道如何分类 编辑: 我正在使用GDCM项目中的vtkGDCMImageReader读取多帧DICOM图像,并使用vtk和pyqt4显示它。我在另一个线程(QThread)中执行此加载,但在加载图像之前,我的应用程序将冻结。下面是一个示例代码: class ReadThread(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())
看一看也许可以在踏板中创建您的读卡器对象:
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())
我猜您正在直接调用
运行
来开始线程。这会使GUI冻结,因为您没有激活线程
因此,您将丢失那里的开始
,这将间接地正确地调用运行
:
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()
有点晚了,但我想我可以指出你面临的问题 图像很大,解包可能是一项CPU密集型任务。这意味着您的GUI线程进入睡眠状态,加载线程受CPU限制。此时加载线程具有GIL,GUI无法启动 即使您可以进入加载线程,并引入睡眠(0),让GUI继续,这对多核或多处理器机器也没有帮助。发生的情况是O/S有两个线程,并且认为它可以同时运行这两个线程。加载线程设置在(比如)Core1上,GUI可以在(比如)Core2上加载和运行。因此,在启动内核2上的GUI线程的加载和启动之后,O/S将恢复内核1上的加载线程,这将导致promtply获取GIL。片刻之后,GUI线程准备启动,并尝试获取GIL,但失败了。没有GIL它能做的就是回去睡觉
一种解决方案是在后台线程中按策略间隔插入一个短睡眠(大于零),以便GUI可以运行。这并不总是可能的 你能给我们看一下相关的代码吗?(精简到最低限度。)
QThread
应该可以工作……是的,我一直在读那篇文章,但事实是,当我试图在单独的QThread或threading.Thread中使用vtggdcmimagereader从gdcm读取一个大的dicom多帧图像文件时,我的UI被阻塞,这是一个I/O操作!!!同样的事情,它阻止了我的UIyes,谢谢你的推理,现在唯一成功的办法是在加载程序的内部C++代码中释放吉尔。我知道流水线中有3.2个补丁,每5ms之间会有两个线程翻转。这可能是一个解决方案。不管是Python的time.sleep还是PyQt的QThread.sleep,都有关系吗?@pygabriel抱歉,我现在删除了断开的链接。但是如果你想看的话,你还是可以看的。非常感谢你提供的chached链接!