处理Python+PyQt实现分级彩色控制台日志的示例代码这类问题时先确认目标场景再按步骤核对配置或玩法细节。
ANSI转义序列ANSI Escape Sequences是一套用于控制终端命令行文本显示格式的标准代码。它起源于20世纪70年代的ANSI X3.64标准通过在普通文本中插入特殊的控制字符序列可以实现改变文本颜色、移动光标位置、清除屏幕区域、设置字体样式如粗体、下划线等多种效果。
概括来看它让原本只能显示黑白文本的命令行窗口变得“五彩斑斓”和“可交互”。
一个典型的ANSI转义序列以转义字符Escape 开头通常是 33八进制、x1b十六进制或 e某些环境。紧随其后的是左方括号 [然后是具体的参数和指令字母。
基本格式33[参数;参数...m
例如33[31m 表示将后续文本设置为红色。
这是最常用的功能用于设置前景色文字颜色、背景色和字体样式。
格式33[代码m
| 样式/颜色 | 前景色代码 | 背景色代码 | 说明 |
|---|---|---|---|
| 重置/默认 | 0 | 0 | 重置所有属性 |
| 粗体/高亮 | 1 | 1 | 文字加粗或变亮 |
| 下划线 | 4 | 4 | 文字带下划线 |
| 闪烁 | 5 | 5 | 文字闪烁部分终端不支持 |
| 反显 | 7 | 7 | 前景背景颜色互换 |
| 黑色 | 30 | 40 | 黑色文字/背景 |
| 红色 | 31 | 41 | 红色文字/背景 |
| 绿色 | 32 | 42 | 绿色文字/背景 |
| 黄色 | 33 | 43 | 黄色文字/背景 |
| 蓝色 | 34 | 44 | 蓝色文字/背景 |
| 品红 | 35 | 45 | 品红色文字/背景 |
| 青色 | 36 | 46 | 青色文字/背景 |
| 白色 | 37 | 47 | 白色文字/背景 |
高级颜色8位/24位真彩色
33[38;5;索引值m前景或 33[48;5;索引值m背景33[38;2;R;G;Bm前景或 33[48;2;R;G;Bm背景控制光标在终端中的位置。
| 功能 | 序列 | 说明 |
|---|---|---|
| 光标上移 | 33[nA | 光标向上移动 n 行 |
| 光标下移 | 33[nB | 光标向下移动 n 行 |
| 光标右移 | 33[nC | 光标向右移动 n 列 |
| 光标左移 | 33[nD | 光标向左移动 n 列 |
| 光标定位 | 33[row;colH 或 33[row;colf | 将光标移动到指定行和列从1开始计数 |
| 保存光标位置 | 33[s | 保存当前光标位置 |
| 恢复光标位置 | 33[u | 恢复到之前保存的光标位置 |
控制终端屏幕的显示。
| 功能 | 序列 | 说明 |
|---|---|---|
| 清屏 | 33[2J | 清除整个屏幕 |
| 清除从光标到行尾 | 33[K | 清除当前行从光标到末尾的内容 |
| 清除从光标到行首 | 33[1K | 清除当前行从开头到光标的内容 |
| 清除整行 | 33[2K | 清除光标所在的整行 |
ls、grep、git 等工具的输出更易读。r和重写实现动态进度条、旋转指示器。33[0m否则后续所有文本都会继承该样式。os.system('color') 或使用 colorama 库来启用ANSI支持。
import sysfrom PyQt6.QtWidgets import QApplication, QMainWindow, QPushButton, QWidget, QVBoxLayoutfrom PyQt6.QtCore import qInstallMessageHandler, QtMsgType, QMutex, QMutexLocker# 全局日志锁log_mutex = QMutex()def my_message_handler(msg_type: QtMsgType, context, msg: str): locker = QMutexLocker(log_mutex) color_code = "" prefix = "" if msg_type == QtMsgType.QtDebugMsg: color_code = "33[36m" prefix = "[D]" elif msg_type == QtMsgType.QtInfoMsg: color_code = "33[32m" prefix = "[I]" elif msg_type == QtMsgType.QtWarningMsg: color_code = "33[33m" prefix = "[W]" elif msg_type == QtMsgType.QtCriticalMsg: color_code = "33[31m" prefix = "[E]" elif msg_type == QtMsgType.QtFatalMsg: color_code = "33[35m" prefix = "[F]" log_line = f"{color_code}{prefix} {msg}33[0mrn" sys.stdout.write(log_line) sys.stdout.flush()class MainWindow(QMainWindow): def __init__(self, parent=None): super().__init__(parent) self.setWindowTitle("Qt Log Demo") self.resize(400, 200) # 安装全局日志处理器 qInstallMessageHandler(my_message_handler) # 自建控件布局 central_widget = QWidget() self.setCentralWidget(central_widget) layout = QVBoxLayout(central_widget) self.btn_test = QPushButton("打印分级日志") layout.addWidget(self.btn_test) # 绑定点击槽 self.btn_test.clicked.connect(self.on_pushButton_clicked) def on_pushButton_clicked(self): from PyQt6.QtCore import qDebug, qInfo, qWarning, qCritical qDebug("this is debug message!") qInfo("this is info message!") qWarning("this is warning message!") qCritical("this is critical message!")if __name__ == "__main__": app = QApplication(sys.argv) w = MainWindow() w.show() sys.exit(app.exec())