2013-04-23 3 views
0

QTextEdit 필드가있는 Gui를 표시하는 코드 조각이 있습니다. 인쇄 기능이 콘솔에 출력하는 것과 비슷한 방식으로 실시간으로이 필드에 인쇄하고 싶습니다.QTextEdit으로 인쇄하여 콘솔로 인쇄하는 방법은 무엇입니까? (Python 3.3)

나는 append 함수의 여러 인스턴스를 사용하여 시도했다. 예 :

self.textEdit.append(_translate("MainWindow", ">>> Text", None)) 

문제는 코드에 어떤 위치가 있더라도 프로그램을 실행 한 후에 만 ​​나타나는 것입니다. 내 목표는 인쇄 기능이 콘솔에서 수행하는 것처럼 라인에 표시되도록하는 것입니다.

나는 쉬운 대답 인 것처럼 느껴진다. 그러나 나는 운을 찾지 않았다. 나는 상당히 새로운 파이썬이고 어떤 도움이나 안내도 감사 할 것이다.

미리 감사드립니다.

답변

2

실제로, 마타에서 언급했듯이 동결은 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이 관심이있을 수 있습니다.

+0

당신 말이 맞아요. 한 파일에서 모든 것을하고있었습니다. 저는 파이썬에 매우 익숙하며 여전히 성장하고 있습니다. 나는 단지 내 직업을위한 생산성 도구를 만들고 싶었다. 내 배경 작업이 "빛"인지 확실하지 않습니다. 이것을 결정할 때 나를 도울 수 있습니까? IP와 포트를 사용하고 무선으로 (셀룰러) 파일을 컴퓨터에서 가져옵니다. 이 파일은 일반적으로 Excel 파일로 다운로드 할 때 10 초에서 10 분 정도 소요될 수 있습니다. 사용자에게 시작 시간과 종료 시간을 알려주고 싶습니다. – mad5245

+1

데이터를 가져 오는 구체적인 방법은 모르겠지만 네트워크 I/O는 비 블로킹이므로 케이스에 안전하게 스레드를 사용할 수 있습니다. 위의 예제에서 while 루프의 코드를 요청 코드로 바꾸면 UI가 응답을 유지하는 것을 볼 수 있습니다. – insys

+0

위의 코드를 실행하려고하면 팝업과 'Start Sleep'이 표시되고 Python이 응답을 중지 한 즉각적인 메시지가 나타납니다. 파이썬을 닫으면 종료 슬립 메시지가 나타납니다. 나는 python 3.3을 사용하고있다. 나는 shouldnt 문제 (나는 print 서술문을 고쳤다)라고 생각한다. 두 번째로는 같은 오류 (파이썬이 멈 춥니 다)하지만 인쇄가 표시되지 않습니다. QWidget :: repaint : 재귀 적 재 페인트가 감지되었다는 메시지. 무슨 생각 이니? (이 도움을 주셔서 감사합니다. 저의 프로그램으로 제 시간에 저를 구할 수 있습니다.) – mad5245

2

즉, GUI 스레드에서 모든 작업을 수행하고있는 것입니다. 이는 흔히 저지르는 실수이며 GUI가 멈추고 계속 진행되는 동안 응답하지 않음을 의미합니다.

QTextEdit의 텍스트를 변경 한 후에 GUI를 업데이트 할 수 있도록 QApplication.processEvents()에 대한 호출을 추가 할 수는 있지만 문제가 부분적으로 만 해결되지만 GUI는 이러한 호출간에 고정됩니다.

솔루션은 간단합니다. 별도의 스레드에서 작업하십시오. Qt 설명서에서 Threading Basics을 읽어보십시오.

+0

응답과 링크에 감사드립니다. 나는 공부할거야. – mad5245

관련 문제