2009-08-21 2 views
2

한 위젯에서 일부 입력을 받아 일부 텍스트 파일을 처리하는 PyQt 앱을 작성하면됩니다.PyQt에서 QTextEdit 새로 고침

현재 사용자가 "프로세스"버튼을 클릭하면 QTextEdit이있는 별도의 창이 열리고 일부 로깅 메시지가 출력됩니다.

Mac OS X에서는이 창이 자동으로 새로 고쳐지고 프로세스가 표시됩니다.

Windows에서이 창은 (응답 없음)을보고 한 후 모든 처리가 완료되면 로그 출력이 표시됩니다. 로그에 기록 할 때마다 창을 새로 고쳐야한다고 가정하고 ive는 타이머를 사용할 때 주위를 둘러 보았습니다. 등,하지만 havnt 그것을 작동 점점 많은 행운을했다.

아래는 소스 코드입니다. 두 파일, 모든 GUI 작업을 수행하는 GUI.py 및 모든 처리를 수행하는 MOVtoMXF 파일이 있습니다.

GUI.py

import os 
import sys 
import MOVtoMXF 
from PyQt4.QtCore import * 
from PyQt4.QtGui import * 


class Form(QDialog): 

    def process(self): 
      path = str(self.pathBox.displayText()) 
      if(path == ''): 
       QMessageBox.warning(self, "Empty Path", "You didnt fill something out.") 
       return 
      xmlFile = str(self.xmlFileBox.displayText()) 
      if(xmlFile == ''): 
       QMessageBox.warning(self, "No XML file", "You didnt fill something.") 
       return 
      outFileName = str(self.outfileNameBox.displayText()) 
      if(outFileName == ''): 
       QMessageBox.warning(self, "No Output File", "You didnt do something") 
       return 
      print path + " " + xmlFile + " " + outFileName 
      mov1 = MOVtoMXF.MOVtoMXF(path, xmlFile, outFileName, self.log) 
      self.log.show() 
      rc = mov1.ScanFile() 
      if(rc < 0): 
       print "something happened" 
      #self.done(0) 


     def __init__(self, parent=None): 
      super(Form, self).__init__(parent) 
      self.log = Log() 
      self.pathLabel = QLabel("P2 Path:") 
      self.pathBox = QLineEdit("") 
      self.pathBrowseB = QPushButton("Browse") 
      self.pathLayout = QHBoxLayout() 
      self.pathLayout.addStretch() 
      self.pathLayout.addWidget(self.pathLabel) 
      self.pathLayout.addWidget(self.pathBox) 
      self.pathLayout.addWidget(self.pathBrowseB) 

      self.xmlLabel = QLabel("FCP XML File:") 
      self.xmlFileBox = QLineEdit("") 
      self.xmlFileBrowseB = QPushButton("Browse") 
      self.xmlLayout = QHBoxLayout() 
      self.xmlLayout.addStretch() 
      self.xmlLayout.addWidget(self.xmlLabel) 
      self.xmlLayout.addWidget(self.xmlFileBox) 
      self.xmlLayout.addWidget(self.xmlFileBrowseB) 


      self.outFileLabel = QLabel("Save to:") 
      self.outfileNameBox = QLineEdit("") 
      self.outputFileBrowseB = QPushButton("Browse") 
      self.outputLayout = QHBoxLayout() 
      self.outputLayout.addStretch() 
      self.outputLayout.addWidget(self.outFileLabel) 
      self.outputLayout.addWidget(self.outfileNameBox) 
      self.outputLayout.addWidget(self.outputFileBrowseB) 

      self.exitButton = QPushButton("Exit") 
      self.processButton = QPushButton("Process") 
      self.buttonLayout = QHBoxLayout() 
      #self.buttonLayout.addStretch() 
      self.buttonLayout.addWidget(self.exitButton) 
      self.buttonLayout.addWidget(self.processButton) 
      self.layout = QVBoxLayout() 
      self.layout.addLayout(self.pathLayout) 
      self.layout.addLayout(self.xmlLayout) 
      self.layout.addLayout(self.outputLayout) 
      self.layout.addLayout(self.buttonLayout) 
      self.setLayout(self.layout) 
      self.pathBox.setFocus() 
      self.setWindowTitle("MOVtoMXF") 

      self.connect(self.processButton, SIGNAL("clicked()"), self.process) 
      self.connect(self.exitButton, SIGNAL("clicked()"), self, SLOT("reject()")) 
      self.ConnectButtons() 


class Log(QTextEdit): 

    def __init__(self, parent=None): 
     super(Log, self).__init__(parent) 
     self.timer = QTimer() 
     self.connect(self.timer, SIGNAL("timeout()"), self.updateText()) 
     self.timer.start(2000) 

    def updateText(self): 
     print "update Called" 

및 MOVtoMXF.py

import os 
import sys 
import time 
import string 
import FileUtils 
import shutil 
import re 

    class MOVtoMXF: 
    #Class to do the MOVtoMXF stuff. 

    def __init__(self, path, xmlFile, outputFile, edit): 
     self.MXFdict = {} 
     self.MOVDict = {} 
     self.path = path 
     self.xmlFile = xmlFile 
     self.outputFile = outputFile 
     self.outputDirectory = outputFile.rsplit('/',1) 
     self.outputDirectory = self.outputDirectory[0] 
     sys.stdout = OutLog(edit, sys.stdout) 



class OutLog(): 

    def __init__(self, edit, out=None, color=None): 
     """(edit, out=None, color=None) -> can write stdout, stderr to a 
     QTextEdit. 
     edit = QTextEdit 
     out = alternate stream (can be the original sys.stdout) 
     color = alternate color (i.e. color stderr a different color) 
     """ 
     self.edit = edit 
     self.out = None 
     self.color = color 



    def write(self, m): 
     if self.color: 
      tc = self.edit.textColor() 
      self.edit.setTextColor(self.color) 

     #self.edit.moveCursor(QtGui.QTextCursor.End) 
     self.edit.insertPlainText(m) 

     if self.color: 
      self.edit.setTextColor(tc) 

     if self.out: 
      self.out.write(m) 
     self.edit.show() 

다른 코드 (내가이 모든 것을이 필요하다고 생각) 필요한 경우 바로 알려 주시기 바랍니다.

도움이 될 것입니다.

마크

당신이, 외부 프로그램을 실행은 QTextEdit에 출력을 캡처하는 것 같습니다

답변

1

. 내가 Form.process 코드를 보지 못했지만, 당신의 함수가 완료하기 위해 외부 프로그램을 기다리는 창에서 추측하고있다가 다음에 QTextEdit에 모든 것을 빠르게 덤프합니다.

인터페이스가 실제로 다른 프로세스가 완료되기를 기다리고 있으면 사용자가 설명하는 방식으로 중단됩니다. 프로그램의 출력을 "비 차단 (non-blocking)"방식으로 얻으려면 하위 프로세스 또는 popen을 조사해야합니다.

"(응답 없음)"을 피하는 열쇠는 QApplication.processEvents을 몇 초마다 몇 번 호출하는 것입니다. QTimer은이 경우에는 도움이되지 않습니다. Qt가 이벤트를 처리 할 수 ​​없으면 신호 처리기를 호출 할 수 없기 때문입니다.

+0

프로세스 이벤트를 볼 수 있도록 코드를 더 추가했습니다. 내가 아는 한 수업을 초기화하는 것입니다. –

+0

큰 파이썬 함수를 실행하는 동안 실제로'sys.stdout'을 포착하는 것처럼 보입니다. 가장 쉬운 방법은'OutLog.write' 메소드의 끝에'qg.QApplication.processEvents()'를 호출하는 것입니다. 그러면 인터페이스에서 무언가가 표준 출력으로 인쇄 될 때마다 업데이트 할 수 있습니다. –