Skip to main content
 首页 » 编程设计

python之在 PyQt 中刷新 QTextEdit

2025年05月04日10yjmyzz

我正在编写一个 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() 

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

任何帮助都会很棒。

标记

请您参考如下方法:

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

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

避免“(Not Responding)”的关键是每隔几秒调用几次QApplication.processEvents。 QTimer 在这种情况下无济于事,因为如果 Qt 无法处理其事件,它就无法调用任何信号处理程序。