import re from PyQt6.QtWidgets import ( QTextEdit, ) from PyQt6.QtGui import ( QColor, QTextCharFormat, QTextCursor ) import color class text_term(QTextEdit): def __init__(self, window, limit = None, *args): super().__init__(*args) self.window = window self.setTabStopDistance(40) self.setReadOnly(True) self.limit = limit def erase_text(self, pos_begin, pos_end): cursor = self.textCursor() cursor.setPosition(pos_begin) cursor.movePosition(QTextCursor.NextCharacter, QTextCursor.KeepAnchor, pos_end - pos_begin) cursor.removeSelectedText() def write(self, s): cursor = self.textCursor() cursor.setPosition(cursor.currentFrame().lastPosition()) ptn_color = r"\x1b\[([0-9]+(?:;[0-9]+)*)m" g = re.finditer(ptn_color, s) pos1 = 0 fmt = QTextCharFormat() fore_color = QColor(200, 200, 200) back_color = QColor(0, 0, 0) for i in g: cursor.insertText(s[pos1:i.span()[0]], fmt) text_color = i.group() match = re.fullmatch(ptn_color, text_color) match = match.group(1) match = [int(i) for i in match.split(";")] # print(text_color, match, file = self.window.stdout_save) match.reverse() flag_normal = False flag_bold = False while match: m = match.pop() if m <= 1: fore_color = QColor(200, 200, 200) back_color = QColor(0, 0, 0) if m == 1: flag_bold = True else: flag_normal = True elif ( 30 <= m <= 37 or 40 <= m <= 47 or 90 <= m <= 97 or 100 <= m <= 107 ): flag = False if m >= 40: m -= 10 flag = True if m >= 90: m -= 90 - 38 m -= 30 if flag_normal: fore_color = color.color_normal_table[m] elif flag_bold: fore_color = color.color_bold_table[m] elif not flag: fore_color = color.color4_table[m] else: back_color = color.color4_table[m] elif m == 38 or m == 48: if m == 38: m = match.pop() m = match.pop() fore_color = color.color8_table[m] elif m == 48: m = match.pop() m = match.pop() back_color = color.color8_table[m] elif m in (39, 49): if m == 39: fore_color = QColor(200, 200, 200) else: back_color = QColor(0, 0, 0) else: # cursor.insertText(text_color) break fmt.setForeground(fore_color) fmt.setBackground(back_color) self.setTextColor(fore_color) pos1 = i.span()[1] cursor.insertText(s[pos1:], fmt) if not (self.limit is None): surplus = self.document().characterCount() - self.limit if surplus > 0: self.erase_text(0, surplus) self.ensureCursorVisible() self.setTextCursor(cursor) def flush(self): pass