如何在 PyQT 中制作实时更新的可编辑小部件

Posted

技术标签:

【中文标题】如何在 PyQT 中制作实时更新的可编辑小部件【英文标题】:How to make a editable widget that updates in live time in PyQT 【发布时间】:2013-12-31 09:40:45 【问题描述】:

我正在尝试制作一个在 PyQT4 中更新我的系统的 GUI。我将使它在 GUI 中实时运行所有命令,以便您可以观看它的更新。我不确定我会使用哪种类型的小部件来做到这一点。

这方面的一个例子就像 wget 在运行时如何拥有下载的状态栏,将其输出放入小部件中。

我想你会使用 subprocess 库来运行命令,然后以某种方式将输出定向到小部件的内容,但我完全不确定如何执行此操作。

非常感谢任何帮助。

【问题讨论】:

【参考方案1】:

我相信你可以使用一个简单的QLabel 实例来完成这个任务。但是,如果您需要更精美的可视化,您也可以使用只读的QTextEdit 等。

至于处理代码,如果你碰巧选择QProcess而不是python中的subprocess模块​​,你会写类似下面的代码。

从 PyQt4.QtCore 导入 QTimer、pyqtSignal、QProcess、pyqtSlot 从 PyQt4.QtGui 导入 QLabel

class SystemUpdate(QProcess)
    """
    A class used for handling the system update process
    """

    def __init__(self):
        _timer = QTimer()
        _myDisplayWidget = QLabel()

        self.buttonPressed.connect(self.handleReadyRead)
        self.error.connect(self.handleError)
        _timer.timeout.connect(self.handleTimeout)

        _timer.start(5000)

    @pyqtSlot()    
    def handleReadyRead(self):
        _readData = readAll()
        _myDisplayWidget.append(readData)

        if not _timer.isActive():
            _timer.start(5000)

    @pyqtSlot()
    def handleTimeout(self):
        if not _readData:
            _myDisplayWidget.append('No data was currently available for reading from the system update')
        else:
            _myDisplayWidget.append('Update successfully run')

    @pyqtSlot(QProcess.ProcessError)
    def handleError(self, processError)
        if processError == QProcess.ReadError:
            _myDisplayWidget.append('An I/O error occurred while reading the data, error: %s' % _process->errorString())

注意:我知道 QLabel 类没有 append 方法,但您可以借助可用方法轻松编写这样一个方便的包装器。

至于完整性,这里是python子进程方法:

import subprocess
from PyQt4.QtGui import QLabel

output = ""
try:
    """
        Here you may need to pass the absolute path to the command
        if that is not available in your PATH, although it should!
    """
    output = subprocess.check_output(['command', 'arg1', 'arg2'], stderr=subprocess.STDOUT)
exception subprocess.CalledProcessError as e:
    output = e.output
finally:
    myDisplayWidget.append(output)

【讨论】:

非常感谢!这对此事非常有用。子流程方法似乎更简单,但我不确定哪个更好。您对使用qprocess 还是subprocess 有什么建议吗? @josh:我的子进程代码是阻塞的,所以我会选择我的 QProcess 代码,除非您将子进程代码修改为非阻塞。 QProcess 阻塞方式将与子进程一样简单,或者至少在那个数量级上。由于系统更新可能需要一段时间,因此最好使用异步方法。您可能可以将一些 Popen 代码与 python 线程放在一起,但我认为 QProcess 代码更好......但这可能只是个人喜好,请原谅我。 :-)

以上是关于如何在 PyQT 中制作实时更新的可编辑小部件的主要内容,如果未能解决你的问题,请参考以下文章

如何在pyqt5中为一个小部件制作一个清晰的板子功能

PyQt5 制作子类小部件

如何使用 PyQt 在小部件上绘制点和线

PyQt5 从主模块外部实时登录 QTextedit

PyQT - 在特定选项卡中引用小部件

如何使 FigureCanvas 在嵌入 pyqt GUI 的 matplotlib 小部件中填充整个 Figure?