Python+PyQt实现分级彩色控制台日志的示例代码

作者:袖梨 2026-08-08

处理Python+PyQt实现分级彩色控制台日志的示例代码这类问题时先确认目标场景再按步骤核对配置或玩法细节。

一、ANSI转义序列介绍

1、什么是ANSI转义序列

ANSI转义序列ANSI Escape Sequences是一套用于控制终端命令行文本显示格式的标准代码。它起源于20世纪70年代的ANSI X3.64标准通过在普通文本中插入特殊的控制字符序列可以实现改变文本颜色、移动光标位置、清除屏幕区域、设置字体样式如粗体、下划线等多种效果。

概括来看它让原本只能显示黑白文本的命令行窗口变得“五彩斑斓”和“可交互”。

一个典型的ANSI转义序列以转义字符Escape 开头通常是 33八进制、x1b十六进制或 e某些环境。紧随其后的是左方括号 [然后是具体的参数和指令字母。

基本格式33[参数;参数...m

例如33[31m 表示将后续文本设置为红色。

2、核心功能与常用序列

文本样式与颜色SGR - Select Graphic Rendition

这是最常用的功能用于设置前景色文字颜色、背景色和字体样式。

格式33[代码m

样式/颜色前景色代码背景色代码说明
重置/默认00重置所有属性
粗体/高亮11文字加粗或变亮
下划线44文字带下划线
闪烁55文字闪烁部分终端不支持
反显77前景背景颜色互换
黑色3040黑色文字/背景
红色3141红色文字/背景
绿色3242绿色文字/背景
黄色3343黄色文字/背景
蓝色3444蓝色文字/背景
品红3545品红色文字/背景
青色3646青色文字/背景
白色3747白色文字/背景

高级颜色8位/24位真彩色

  1. 8位256色33[38;5;索引值m前景或 33[48;5;索引值m背景
  2. 24位真彩色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;colH33[row;colf将光标移动到指定行和列从1开始计数
保存光标位置33[s保存当前光标位置
恢复光标位置33[u恢复到之前保存的光标位置

屏幕控制

控制终端屏幕的显示。

功能序列说明
清屏33[2J清除整个屏幕
清除从光标到行尾33[K清除当前行从光标到末尾的内容
清除从光标到行首33[1K清除当前行从开头到光标的内容
清除整行33[2K清除光标所在的整行

3、常见应用场景

  1. 命令行工具美化lsgrepgit 等工具的输出更易读。
  2. 日志系统区分不同级别的日志ERROR-红色WARN-黄色INFO-绿色DEBUG-蓝色。
  3. 进度指示器通过光标回退r和重写实现动态进度条、旋转指示器。
  4. 交互式CLI应用通过光标定位实现菜单选择、表单填写等复杂界面。
  5. 终端游戏与动画实现简单的字符动画效果。

4、注意事项与兼容性

  1. 并非所有终端都支持古老的终端或某些环境如Windows旧版cmd可能不支持部分序列。现代终端如Windows Terminal, iTerm2, GNOME Terminal通常支持良好。
  2. 重置序列使用样式后务必在结尾添加重置序列 33[0m否则后续所有文本都会继承该样式。
  3. Windows特殊处理在Python中Windows系统可能需要调用 os.system('color') 或使用 colorama 库来启用ANSI支持。
  4. 性能考虑过度频繁地输出转义序列可能会影响性能尤其是在输出大量文本时。
  5. 可访问性屏幕阅读器可能无法正确解析颜色代码重要信息不应仅靠颜色区分。

二、源码分享

效果展示

Python+PyQt实现分级彩色控制台日志的示例代码

源码分享

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())

相关文章

精彩推荐