2

我正在编写一个 PyQt 应用程序,它在一个小部件中接受一些输入,然后处理一些文本文件。

我目前得到的是,当用户单击“进程”按钮时,会弹出一个带有 QTextEdit 的单独窗口,并输出一些日志消息。

在 Mac OS X 上,此窗口会自动刷新,您可以看到该过程。

在 Windows 上,窗口报告(未响应),然后在完成所有处理后,将显示日志输出。我假设我需要在每次写入日志后刷新窗口,并且我环顾四周使用计时器。等等,但是在让它工作方面有很大的运气。

下面是源代码。它有两个文件,GUI.py 完成所有的 GUI 工作,MOVtoMXF 完成所有的处理。

图形用户界面.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()

如果需要任何其他代码(我认为这就是所有需要的),请告诉我。

任何帮助都会很棒。

标记

4

1 回答 1

1

It looks like your are running an external program, capturing its output into a QTextEdit. I didn't see the code of Form.process, but I am guessing on windows your function waits for the external program to finish, then quickly dumps everything to the QTextEdit.

If your interface really is waiting for the other process to finish, then it will hang in the manner you describe. You'll need to look at subprocess or perhaps even popen to get the program's output in a "non-blocking" manner.

The key to avoiding "(Not Responding)" is to call QApplication.processEvents a few times every few seconds. The QTimer is not going to help in this case, because if Qt cannot process its events, it cannot call any signal handlers.

于 2009-08-21T05:36:12.407 回答