2009-08-21 32 views
2

Imは1つのウィジェットで何らかの入力を受け取り、いくつかのテキストファイルを処理するPyQtアプリケーションを記述しています。PyQtのQTextEditを更新する

ユーザーが「プロセス」ボタンをクリックすると、別のウィンドウにQTextEditがポップアップして表示され、いくつかのログメッセージが出力されます。

Mac OS Xでは、このウィンドウが自動的に更新され、プロセスが表示されます。

Windowsでは、ウィンドウは(応答なし)を報告し、すべての処理が完了するとログ出力が表示されます。私はログに書き込むたびにウィンドウをリフレッシュする必要があると仮定し、タイブを使用する際にはiveを見ていました。しかし、havntはそれを稼働させることに多くの運があった。

以下はソースコードです。 2つのファイル、すべての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のコードを見ませんでしたが、私はあなたの機能が完了するために外部プログラムを待っているWindowsを推測していますし、すぐにすべてをQTextEditにダンプします。

インターフェイスが本当に他のプロセスが完了するのを待っている場合は、記述した方法でハングアップします。あなたは、プログラムの出力を "非ブロッキング"なやり方で得るために、サブプロセス、あるいはおそらくpopenを見る必要があります。

「応答しない」を避けるための鍵は、QApplication.processEventsを数秒ごとに数回呼び出すことです。 QTimerは、Qtがイベントを処理できない場合、シグナルハンドラを呼び出すことができないため、この場合は役に立ちません。

+0

コードをもう少し追加して、プロセスイベントを見ることができます。限り、私はクラスを初期化していると言うことができます。 –

+0

大きなPython関数を実行している間に 'sys.stdout'を実際にキャプチャしているようです。試みるのが最も簡単なのは、 'OutLog.write'メソッドの最後に' qg.QApplication.processEvents() 'を呼び出すことです。そうすれば、何かがstdoutにプリントされるときにいつでもインターフェースが更新されるでしょう。 –

関連する問題