[英]PyQt4, QThread and opening big files without freezing the GUI
我想問一下如何從磁盤讀取一個大文件並保持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())
我猜你是直接調用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()
有點晚了,但我想我可以找出你面臨的問題。
圖像很大,解壓縮可能是CPU密集型任務。 這意味着您的GUI線程進入休眠狀態,加載線程受CPU限制。 此時加載線程具有GIL,GUI無法啟動。
即使您可以進入加載線程並引入sleep(0),以使GUI繼續運行,這對於多核處理器或多處理器機器也無濟於事。 發生的事情是O / S有兩個線程,並認為它可以同時運行。 加載線程設置在(例如)核心1上,GUI可以加載並運行(例如)核心2.因此,在核心2上啟動加載並啟動GUI線程后,O / S恢復加載線程在核心1 - 它突然抓住了GIL。 片刻之后,GUI線程就可以開始了,並嘗試獲取失敗的GIL。 沒有GIL它可以做的就是回去睡覺!
一種解決方案是以策略間隔在后台線程中插入一個短(大於零)睡眠,以便GUI可以運行。 這並不總是可行的。
也許在踏板中創建您的讀者對象:
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())
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.