代码之家  ›  专栏  ›  技术社区  ›  beesleep

在QplaintExtendit中使用TQM显示终端输出

  •  2
  • beesleep  · 技术社区  · 7 年前

    我面临的问题是,进度条可以使用一些更高级的回车符,或者甚至是更高级的光标定位,而这些大多是Tream不支持的。 io.StringIO ,但 \r 保持文字不变。

    import io
    from tqdm import tqdm
    s = io.StringIO()
    for i in tqdm(range(3), file=s):    
        sleep(.1)
    

    输出:

    s.getvalue()
    
    Out[24]: '\n\r  0%|          | 0/3 [00:00<?, ?it/s]\x1b[A\n\r 33%|###3      | 1/3 [00:00<00:00,  9.99it/s]\x1b[A\n\r 67%|######6   | 2/3 [00:00<00:00,  9.98it/s]\x1b[A\n\r100%|##########| 3/3 [00:00<00:00,  9.98it/s]\x1b[A\n\x1b[A'
    

    这转化为:

    print(s.getvalue())
      0%|          | 0/3 [00:00<?, ?it/s]
     33%|###3      | 1/3 [00:00<00:00,  9.99it/s]
     67%|######6   | 2/3 [00:00<00:00,  9.98it/s]
    100%|##########| 3/3 [00:00<00:00,  9.98it/s]
    

    你知道怎么做吗? 谢谢

    1 回复  |  直到 7 年前
        1
  •  3
  •   eyllanesc    7 年前

    如果添加了新文本,可以删除前一行,但也必须删除 \r 并验证它不是空文本。此外,对于要接收的文本的对象 tqdm write() QPlainTextEdit . 使用 QMetaObject::invokeMethod() 使其线程安全

    import time
    import threading
    from tqdm import tqdm
    from PyQt5 import QtCore, QtGui, QtWidgets
    import lorem
    
    class LogTextEdit(QtWidgets.QPlainTextEdit):
        def write(self, message):
            if not hasattr(self, "flag"):
                self.flag = False
            message = message.replace('\r', '').rstrip()
            if message:
                method = "replace_last_line" if self.flag else "appendPlainText"
                QtCore.QMetaObject.invokeMethod(self,
                    method,
                    QtCore.Qt.QueuedConnection, 
                    QtCore.Q_ARG(str, message))
                self.flag = True
            else:
                self.flag = False
    
        @QtCore.pyqtSlot(str)
        def replace_last_line(self, text):
            cursor = self.textCursor()
            cursor.movePosition(QtGui.QTextCursor.End)
            cursor.select(QtGui.QTextCursor.BlockUnderCursor)
            cursor.removeSelectedText()
            cursor.insertBlock()
            self.setTextCursor(cursor)
            self.insertPlainText(text)
    
    def foo(w):
        for i in tqdm(range(100), file=w):
            time.sleep(0.1)
    
    if __name__ == '__main__':
        import sys
        app = QtWidgets.QApplication(sys.argv)
        w = LogTextEdit(readOnly=True)
        w.appendPlainText(lorem.paragraph())
        w.appendHtml("Welcome to Stack Overflow")
        w.show()
        threading.Thread(target=foo, args=(w,), daemon=True).start()
        sys.exit(app.exec_())