如何将tqdm文本内容流式传输到PySide2 GUI?

0 投票
2 回答
34 浏览
提问于 2025-04-14 17:00

我正在使用 jMetalPy。它有一个叫做 "ProgressBarObserver" 的功能,利用 tqdm 来显示计算进度。

https://github.com/jMetal/jMetalPy/blob/main/jmetal/util/observer.py

我有一个基于 PySide2 的图形界面,它可以在界面上显示控制台的内容,令我惊讶的是,除了 tqdm 的内容,其他的都能在界面上显示出来。

    class EmittingStream(QtCore.QObject):
        textWritten = Signal(str)

        def write(self, text):
            self.textWritten.emit(text)

        def flush(self):
            pass

.....

# Console print
    self.textBrowser = self.ui.textBrowser_log


    # Create a custom stream object for the QTextBrowser.
    self.textBrowserStream = EmittingStream()
    self.textBrowserStream.textWritten.connect(self.textBrowser.append)

    # Redirect output to the QTextBrowser, but not the output from pandas.
    sys.stdout = self.textBrowserStream
    pd.option_context('display.max_rows', None, 'display.max_columns', None, 'display.expand_frame_repr', False)

我在使用 PyCharm,控制台的打印内容是白色的,但 tqdm 的内容是红色的,显然这些文本是不同的,可能需要用不同的方式来处理。我该如何让这些内容也能出现在我的文本流输出中呢? 为了更清楚地说明,tqdm 的内容在 PyCharm 中显示正常,但在 PySide2 的图形界面中只显示了普通的白色文本打印语句。谢谢!

2 个回答

0

穆罕默德的回答听起来像是个糟糕的AI回复。

我最后修改了jMetalpy的ProgressBarObserver类,添加打印语句对我来说就足够了。它会在控制台或图形界面上循环打印进度。

class ProgressBarObserver(Observer):

    def __init__(self, max: int) -> None:
        """ Show a smart progress meter with the number of evaluations and computing time.

        :param max: Number of expected iterations.
        """
        self.progress_bar = None
        self.progress = 0
        self._max = max

    def update(self, *args, **kwargs):
        if not self.progress_bar:
            self.progress_bar = tqdm(total=self._max, ascii=True, desc='Progress')

        evaluations = kwargs['EVALUATIONS']

        self.progress_bar.update(evaluations - self.progress)
        self.progress = evaluations
        
        ### I added this line here ###
        print(f"Evaluations: {evaluations}", file=sys.stdout)**

        if self.progress >= self._max:
            self.progress_bar.close()
0

看起来你遇到的问题可能是因为tqdm的输出处理方式和普通的打印语句不一样。tqdm使用一些特殊的控制代码来动态更新进度条,而这些代码在重定向到QTextBrowser时可能无法正确显示。

为了在你的PySide2图形界面中处理tqdm的输出,你需要单独拦截和处理tqdm的输出。一种方法是从jMetalPy的ProgressBarObserver类继承一个新的类,并重写它的on_progress_bar_update方法,这样就可以发出信号来更新tqdm的进度。然后,你可以把这些信号连接到你的图形界面上,以便进行更新。

--- 将tqdm观察者添加到图形界面 ----

tqdm_observer = TqdmProgressBarObserver()
self.textBrowser.add_tqdm_observer(tqdm_observer)

撰写回答