python - 在 QPlainTextEdit 中使用 tqdm 显示终端输出
问题描述
我正在尝试找到一种方法来获取 pyqt 应用程序中进度条的结果/演变以及其他打印,例如在 QPlainTextEdit 小部件中。
我面临的问题是进度条可以使用一些更高级的回车,甚至更高级的光标定位,这些大多不被treams 支持。我试过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]
需要明确的是,在我的输出中,我不希望每次 tqdm 更新一行,而只希望当前状态,因为它将打印在命令行上。
知道怎么做吗?谢谢!
解决方案
这个想法是如果添加了新文本,则删除前一行,但您还必须删除\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_())
推荐阅读
- php - 如何将外部表列分组到不同的表下?
- r - R中的条件累积和时间序列列
- html - 前景文本与背景具有相同的过滤器
- android - 如何在 android 中强制设置“ImageView”字段?
- stored-procedures - 带有返回参数的存储过程 - “ODBC 驱动程序不支持请求的属性”?
- firebase - Firestore 聊天应用程序 - 构建消息主页
- python - What is the canonical representation of a point in numpy?
- c# - 网页在 Chrome 浏览器上正常加载,但是在使用 chromedriver selenium 时加载为空
- mysql - 如何使用颤振以下拉形式从 phpmyadmin 检索数据
- javascript - 用于在 HTML 字符串中提取数据的正则表达式