【问题标题】:Refresh QTextEdit in PyQt在 PyQt 中刷新 QTextEdit
【发布时间】:2012-10-21 19:38:57
【问题描述】:

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

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

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

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

以下是源代码。它有两个文件,GUI.py 负责所有的 GUI 工作,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"

AND 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()

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

任何帮助都会很棒。

标记

【问题讨论】:

    标签: python pyqt


    【解决方案1】:

    看起来您正在运行一个外部程序,将其输出捕获到 QTextEdit 中。我没有看到Form.process 的代码,但我猜在Windows 上你的函数会等待外部程序完成,然后迅速将所有内容转储到QTextEdit

    如果您的界面确实在等待其他进程完成,那么它将以您描述的方式挂起。您需要查看 subprocess 甚至可能 popen 以“非阻塞”方式获取程序的输出。

    避免“(未响应)”的关键是每隔几秒拨打几次QApplication.processEventsQTimer 在这种情况下没有帮助,因为如果 Qt 不能处理它的事件,它就不能调用任何信号处理程序。

    【讨论】:

    • 我添加了更多代码,以便您查看流程事件。据我所知,它只是初始化一个类。
    • 所以看起来你在运行一个大的 Python 函数时实际上是在捕获sys.stdout。最简单的尝试是在OutLog.write 方法的末尾调用qg.QApplication.processEvents()。然后,界面将有机会在打印到标准输出的任何时候进行更新。
    猜你喜欢
    • 1970-01-01
    • 2016-07-12
    • 2020-05-30
    • 2018-09-18
    • 2019-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-01
    相关资源
    最近更新 更多