실제로, 마타에서 언급했듯이 동결은 UI 업데이트를 처리하는 동일한 (메인) 스레드에서 모든 작업을 수행 할 때 발생합니다. 응답 성 문제를 해결하는 한 가지 방법은 참으로 차단 코드에서 QApplication.processEvents()를 자주 사용하는 것입니다. 그렇게하면 빈번한 사용자 응답 GUI의 인상을 줄 것입니다.
그러나 Python에서 스레드를 사용하면 (기본 또는 QThread) 항상 작동하지는 않습니다. 이는 Global Interpreter Lock (GIL, the wiki has a good short intro)의 존재 때문입니다. 즉, 파이썬은 하나 이상의 스레드가 동시에 코드를 실행할 수 없게합니다.
백그라운드 작업이 가볍거나 IO를 기반으로하는 경우 작업을 수행하는 동안 Python에서 IO를 많이 사용하는 모듈이 릴리스되므로이 문제를 해결할 수 있습니다. 그러나 파이썬에서 계산량이 많은 경우 GIL은 프로세스에 의해 잠겨 지므로 UI가 여전히 응답하지 않습니다.
는 PySide 사용하여, 다음과 같은 예를 내장 고려 :
import sys, random
from threading import Thread
from time import sleep
from urllib import urlopen
from PySide import QtCore, QtGui
class Window(QtGui.QMainWindow):
update_signal = QtCore.Signal(int)
def __init__(self):
QtGui.QMainWindow.__init__(self)
self.progress_bar = QtGui.QProgressBar(self)
self.progress_bar.setRange(0, 10)
self.setCentralWidget(self.progress_bar)
self.update_signal[int].connect(self.progress_bar.setValue)
self.show()
self.t = Thread(target=self.worker)
self.t.start()
def worker(self):
while self.progress_bar.value() < 10:
self.update_signal.emit(self.progress_bar.value()+1)
print "Starting Sleep"
sleep(5)
print "End of Sleep"
if __name__ == '__main__':
qapp = QtGui.QApplication(sys.argv)
win = Window()
sys.exit(qapp.exec_())
를 그런 다음에 작업자의 기능을 대체하려고 : 호출이 잠을로 (
이
def worker(self):
while self.progress_bar.value() < 10:
self.update_signal.emit(self.progress_bar.value()+1)
v = 0
print "Starting Add"
for i in xrange(5000000):
v = v+random.uniform(0, 100)
print "End of Add"
첫 번째 경우는 반응 UI를 유지) GIL을 출시합니다. 그러나 두 번째 예제는 연산 집약적 인 알고리즘이 잠금을 유지하므로 그렇지 않습니다.
하나의 솔루션은 multiprocessing 패키지를 사용할 수 있습니다. 워드 프로세서 :
멀티 스레딩 모듈과 유사한 API를 사용하여 산란 프로세스를 지원하는 패키지입니다.다중 처리 패키지 은 로컬 및 원격 동시성을 모두 제공하므로 스레드 대신 하위 프로세스를 사용하여전역 인터프리터 잠금을 효과적으로 사이드 스테핑합니다. 이 때문에 멀티 프로세싱 모듈을 사용하면 프로그래머는 주어진 시스템에서 복수 프로세서를 완벽하게 활용할 수 있습니다 ( ). 당신이 더 관심을 가지고있는 경우 A simple, illustrative example of using python multipocessing.
또한,
this blog post about multi-processing techniques이 관심이있을 수 있습니다.
당신 말이 맞아요. 한 파일에서 모든 것을하고있었습니다. 저는 파이썬에 매우 익숙하며 여전히 성장하고 있습니다. 나는 단지 내 직업을위한 생산성 도구를 만들고 싶었다. 내 배경 작업이 "빛"인지 확실하지 않습니다. 이것을 결정할 때 나를 도울 수 있습니까? IP와 포트를 사용하고 무선으로 (셀룰러) 파일을 컴퓨터에서 가져옵니다. 이 파일은 일반적으로 Excel 파일로 다운로드 할 때 10 초에서 10 분 정도 소요될 수 있습니다. 사용자에게 시작 시간과 종료 시간을 알려주고 싶습니다. – mad5245
데이터를 가져 오는 구체적인 방법은 모르겠지만 네트워크 I/O는 비 블로킹이므로 케이스에 안전하게 스레드를 사용할 수 있습니다. 위의 예제에서 while 루프의 코드를 요청 코드로 바꾸면 UI가 응답을 유지하는 것을 볼 수 있습니다. – insys
위의 코드를 실행하려고하면 팝업과 'Start Sleep'이 표시되고 Python이 응답을 중지 한 즉각적인 메시지가 나타납니다. 파이썬을 닫으면 종료 슬립 메시지가 나타납니다. 나는 python 3.3을 사용하고있다. 나는 shouldnt 문제 (나는 print 서술문을 고쳤다)라고 생각한다. 두 번째로는 같은 오류 (파이썬이 멈 춥니 다)하지만 인쇄가 표시되지 않습니다. QWidget :: repaint : 재귀 적 재 페인트가 감지되었다는 메시지. 무슨 생각 이니? (이 도움을 주셔서 감사합니다. 저의 프로그램으로 제 시간에 저를 구할 수 있습니다.) – mad5245