def apply_filter(self, *args): text = self.filterEdit.text() if text: if self.filter_columns.currentText() == "name": m = QRegularExpression(text) if m.isValid(): if self.name_regex_option.currentText( ) == "case-insensitive": m.setPatternOptions( QRegularExpression.CaseInsensitiveOption) m.optimize() filter = lambda row_num: m.match( self.table.item(row_num, 0).text()).hasMatch() else: return elif self.filter_columns.currentText() == "denticity": if text.isdigit(): filter = lambda row_num: int( self.table.item(row_num, 1).text()) == int(text) else: filter = lambda row: True elif self.filter_columns.currentText() == "coordinating elements": method = self.coordinating_elements_method.currentText() def filter(row_num): row_key_atoms = [ item.strip() for item in self.table.item( row_num, 2).text().split(',') ] search_atoms = [] for item in text.split(): for ele in item.split(','): if ele.strip() != "": search_atoms.append(ele) if method == "exactly": if all([row_key_atoms.count(element) == search_atoms.count(element) for element in set(search_atoms)]) and \ all([row_key_atoms.count(element) == search_atoms.count(element) for element in set(row_key_atoms)]): return True else: return False elif method == "at least": if all([ row_key_atoms.count(element) >= search_atoms.count(element) for element in set(search_atoms) ]): return True else: return False else: filter = lambda row: True for i in range(0, self.table.rowCount()): self.table.setRowHidden(i, not filter(i))
class WorkspaceNameValidator(QValidator): def __init__(self): self.regex = QRegularExpression(r"^.{1,256}$") def validate(self, string, pos): if self.regex.match(string, pos).hasMatch(): return QValidator.Acceptable, string, pos return QValidator.Invalid, string, pos
def rxExecute(regexp, options, text, startpos): """ Function to execute the given regular expression for a given text. @param regexp regular expression to validate (string) @param options list of options (list of string) @param text text to execute on (string) @param startpos start position for the execution (integer) @return tuple of a flag indicating a successful match (boolean) and a list of captures containing the complete match as matched string (string), match start (integer), match end (integer) and match length (integer) for each entry """ valid, error, errorOffset = rxValidate(regexp, options) if not valid: return valid, error, errorOffset from PyQt5.QtCore import QRegularExpression rxOptions = QRegularExpression.NoPatternOption if "CaseInsensitiveOption" in options: rxOptions |= QRegularExpression.CaseInsensitiveOption if "MultilineOption" in options: rxOptions |= QRegularExpression.MultilineOption if "DotMatchesEverythingOption" in options: rxOptions |= QRegularExpression.DotMatchesEverythingOption if "ExtendedPatternSyntaxOption" in options: rxOptions |= QRegularExpression.ExtendedPatternSyntaxOption if "InvertedGreedinessOption" in options: rxOptions |= QRegularExpression.InvertedGreedinessOption if "UseUnicodePropertiesOption" in options: rxOptions |= QRegularExpression.UseUnicodePropertiesOption if "DontCaptureOption" in options: rxOptions |= QRegularExpression.DontCaptureOption matched = False captures = [] re = QRegularExpression(regexp, rxOptions) match = re.match(text, startpos) if match.hasMatch(): matched = True for index in range(match.lastCapturedIndex() + 1): captures.append([ match.captured(index), match.capturedStart(index), match.capturedEnd(index), match.capturedLength(index) ]) return matched, captures
class BinValidator(QValidator): def __init__(self, max_bits=-1, bit_group_size=4): super().__init__() self.max_bits = max_bits self.bit_group_size = bit_group_size if max_bits == 0: self.re_acceptable = QRegularExpression('') elif max_bits > 0: self.re_acceptable = QRegularExpression( '^([0,1](\s[0,1]){0,%d})?$' % (max_bits - 1)) self.re_intermediate = QRegularExpression('^(\s*[0,1]){0,%d}\s*$' % (max_bits)) else: self.re_acceptable = QRegularExpression('^([0,1](\s[0,1])*)?$') self.re_intermediate = QRegularExpression('^(\s*[0,1])*\s*$') def validate(self, text, _pos): text = text.upper() if self.re_acceptable.match(text).hasMatch(): return QValidator.Acceptable, text, _pos if self.re_intermediate.match(text).hasMatch(): return QValidator.Intermediate, text, _pos return QValidator.Invalid, text, _pos def fixup(self, text): text = text.replace(' ', '') fixed = ' '.join([ text[i:i + self.bit_group_size] for i in range(0, len(text), self.bit_group_size) ]) return fixed
def apply_filter(self, *args): text = self.filterEdit.text() if text: if self.filter_columns.currentText() == "name": m = QRegularExpression(text) if m.isValid(): if self.name_regex_option.currentText( ) == "case-insensitive": m.setPatternOptions( QRegularExpression.CaseInsensitiveOption) m.optimize() filter = lambda row_num: m.match( self.table.item(row_num, 0).text()).hasMatch() else: return else: filter = lambda row: True for i in range(0, self.table.rowCount()): self.table.setRowHidden(i, not filter(i))
def apply_filter(self, text=None): if text is None: text = self.filter.text() if text: text = text.replace("(", "\(") text = text.replace(")", "\)") m = QRegularExpression(text) m.setPatternOptions(QRegularExpression.CaseInsensitiveOption) if m.isValid(): m.optimize() filter = lambda row_num: m.match( self.table.item(row_num, 0).text() if self.table.item(row_num, 0) is not None else self.table. cellWidget(row_num, 0).text().replace("<sub>", "").replace( "</sub>", "")).hasMatch() else: return else: filter = lambda row: True for i in range(0, self.table.rowCount()): self.table.setRowHidden(i, not filter(i))
def occurenceLineList(self, regex: QRegularExpression) -> List[int]: res = [] for ind, line in enumerate(self._contentList): if regex.match(line).hasMatch(): res.append(ind) return res
def contains(self, regex: QRegularExpression, useRegExp=True) -> bool: if useRegExp: match: QRegularExpressionMatch = regex.match(self._content) return match.hasMatch() else: return regex.pattern().lower() in self._contentLower
def valueFromText(text): regExp = QRegularExpression("(\\d+)(\\s*[xx]\\s*\\d+)?") match = regExp.match(text) if match.isValid(): return match.captured(1).toInt() return 0
class GMHighlighter(QSyntaxHighlighter): def __init__(self, document, base, proc_class): QSyntaxHighlighter.__init__(self, document) self.reversal_post_processor = proc_class(base) self.list_number_captured_1 = [i * 2 for i in range(1, 15)] #todo добавь ijk self.list_number_captured_1.insert(3, 6) self.previous_block_g = 0 self.base = base self.count = 0 self.count_in_step = 0 self.const_step = 1000 self.standart_step = self.const_step self.main_rule_regular_expression = QRegularExpression( self.reversal_post_processor.sorted_axis_rule) self.simple_format = STYLES['axis'] #self.first_rule[2] self.second_rule_regular_expression = QRegularExpression( self.reversal_post_processor.unsorted_axis_rule) #self.rules[0][0] self.too_little_number_check() print(self.main_rule_regular_expression) def remember_np_box_parts(self, current_pool): self.current_g_cod_pool = current_pool #print('1 self.current_g_cod_pool = ') #print(self.current_g_cod_pool) #print('2 self.current_g_cod_pool = ') def too_little_number_check(self): print('too_little_number_check') if self.base.reading_lines_number < self.const_step: self.standart_step = self.base.reading_lines_number def highlightBlock(self, text): """Применить выделение синтаксиса к данному блоку текста. """ #print('highloght text = [{}]'.format(text) ) nya = self.main_rule_regular_expression.match(text, 0) #print('nya0 = ', nya.captured(0)) start = nya.capturedStart() len_match = nya.capturedLength() if len_match != 0: #print('nya = ', nya.captured()) self.recount(nya, STYLES_list_G0, STYLES_list_G1) elif start == 0: print('empty string') self.recount_empty_line() #print('index = {}, string = {}, запуск дополнительных правил'.format(index, text)) else: nya = self.second_rule_regular_expression.match(text, 0) len_match = nya.capturedLength() if len_match != 0: self.unsorted_recount(nya, STYLES_list_G0, STYLES_list_G1) else: if not self.recount_special_rules(text): print('ERROR LINE: ', text) def recount_empty_line(self): self.current_g_cod_pool[self.count][2] = self.previous_block_g self.current_g_cod_pool[self.count][16] = 9999 #type self.count_in_step += 1 self.count += 1 if self.count_in_step == self.standart_step: self.base.on_count_changed(self.count) # progressBar return def recount_special_rules(self, text): self.current_g_cod_pool[self.count][3] = self.previous_block_g result = self.special_rare_case(text, self.count) self.count_in_step += 1 self.count += 1 if self.count_in_step == self.standart_step: self.base.on_count_changed(self.count) # progressBar return result def special_rare_case(self, text, count): #print('self.base.current_g_cod_pool[self.count] ', self.base.current_g_cod_pool[self.count]) #G28 U0. V0. print('text = ', text) if self.reversal_post_processor.check_command( self, text, self.current_g_cod_pool[count], count, self.base.g_modal): #todo это не тот g_modal return True else: return False #print('self.start_pointXYZ = ', self.reversal_post_processor.start_pointXYZ) def recount(self, nya, STYLES_list_G0, STYLES_list_G1): #print('recount self.current_g_cod_pool = ', self.current_g_cod_pool) self.current_g_cod_pool[self.count, np.r_[0:15]] = [ nya.captured(i) or None for i in self.list_number_captured_1 ] #print('uuuu nya.captured(6) = ', nya.captured(6)) #Заполнения здесь не происходит, так как оно только между numpy массивами #print('current_g_cod_pool == ', self.base.current_g_cod_pool[self.count]) #G0-G3 if np.isnan(self.current_g_cod_pool[self.count][3]): self.current_g_cod_pool[self.count][3] = self.previous_block_g else: self.previous_block_g = self.current_g_cod_pool[self.count][3] self.current_g_cod_pool[self.count, 2] = self.previous_block_g stile = STYLES_list_G0 if self.previous_block_g == 0 else STYLES_list_G1 #colors # простая подсветка одним цветом # self.setFormat(index, len_match, self.simple_format) #полноценная подсветка i = 0 ax = len(nya.captured(i * 2 + 1)) start = 0 #if ax != 0: # self.setFormat(start, ax, stile[i]) #start = start + ax #i = i + 1 #print('i equal ', i) #for k in range(40): # print('recount: ||||nya.captured({}) = {}'.format(k, nya.captured(k))) while i < 14: #todo надо подумать. По идее надо добавлять +1 строку в style, но работало, вроде... if ax != 0: self.setFormat(start, ax, stile[i]) #print('i = ', i) #print('stile[i] = ', stile[i]) start = start + ax i = i + 1 ax = len(nya.captured(i * 2 + 1)) #print('recount current_g_cod_pool again == ', self.current_g_cod_pool[self.count]) self.count_in_step += 1 self.count += 1 if self.count_in_step == self.standart_step: self.base.on_count_changed(self.count) #QApplication.processEvents() #print('Count') return def unsorted_recount(self, nya, STYLES_list_G0, STYLES_list_G1): print('unsorted_recount start') #for i in range(35): # print('nya.captured({}) = {}'.format(i, nya.captured(i))) # G0-G3 self.current_g_cod_pool[self.count][0] = nya.captured(2) or None self.current_g_cod_pool[self.count][1] = nya.captured(4) or None self.current_g_cod_pool[self.count][2] = nya.captured(6) or None if np.isnan(self.current_g_cod_pool[self.count][2]): self.current_g_cod_pool[self.count][3] = self.previous_block_g else: self.previous_block_g = self.current_g_cod_pool[self.count][2] self.current_g_cod_pool[self.count][3] = self.previous_block_g stile = STYLES_list_G0 if self.previous_block_g == 0 else STYLES_list_G1 start = 0 n = 1 #N ax = len(nya.captured(n)) #print('n === ', n) #print('nya.captured(n) = ', nya.captured(n)) #print(' ax == ', ax ) #print('start === ', start) if ax != 0: self.setFormat(start, ax, stile[0]) #N start = start + ax n = n + 2 ax = len(nya.captured(n)) if ax != 0: self.setFormat(start, ax, stile[1]) #G40 start = start + ax n = n + 2 ax = len(nya.captured(n)) if ax != 0: self.setFormat(start, ax, stile[2]) #G1 start = start + ax n = n + 2 ax = len(nya.captured(n)) #if ax != 0: # self.setFormat(start, ax, stile[n-1]) # start = start + ax #n = n + 2 #ax = len(nya.captured(n)) n = n + 1 #print('n === ', n) #for k in range(40): # print('||||nya.captured({}) = {}'.format(k, nya.captured(k))) #n = 4 while nya.captured(n) != '' and n < 26: #вероятно, избыточное условие self.nesting(n, nya, start, ax, stile) start = start + ax n = n + 3 ax = len(nya.captured(n - 1)) #n = 26 #ax = len(nya.captured(n))#todo нужно будет разделить координаты точки и IJK или уже? while nya.captured(n) != '' and n < 33: #ijk self.nestingIJK(n, nya, start, ax, stile) start = start + ax n = n + 3 ax = len(nya.captured(n - 1)) #print('n = {}, ax = {}'.format(n, ax)) #for i in range (33): # print('nya.captured({}) = {}'.format(i, nya.captured(i))) n = 35 ax = len(nya.captured(n - 1)) print('n 2=== ', n) #ax = len(nya.captured(34)) if ax != 0: self.setFormat(start, ax, stile[12]) start = start + ax self.current_g_cod_pool[self.count][13] = nya.captured(35) or None #R #ax = len(nya.captured(29)) n = 37 ax = len(nya.captured(n - 1)) if ax != 0: self.setFormat(start, ax, stile[13]) #start = start + ax self.current_g_cod_pool[self.count][14] = nya.captured(37) or None #F print('unsorted recount current_g_cod_pool again == ', self.current_g_cod_pool[self.count]) self.count_in_step += 1 self.count += 1 if self.count_in_step == self.standart_step: self.base.on_count_changed(self.count) # progressBar # QApplication.processEvents() return def nestingIJK(self, n, nya, start, ax, stile): print('nestingIJK') add = 2 symbol = nya.captured(n) if symbol == 'I': i = 7 + add elif symbol == 'J': i = 8 + add elif symbol == 'K': i = 9 + add else: print('Ты не должен сюда попасть, но вдруг 1') return self.setFormat(start, ax, stile[i]) self.current_g_cod_pool[self.count][i + 1] = nya.captured(n + 1) def nesting(self, n, nya, start, ax, stile): print('nesting s') add = 2 symbol = nya.captured(n) if symbol == 'X': i = 1 + add elif symbol == 'Y': i = 2 + add elif symbol == 'Z': i = 3 + add elif symbol == 'C': i = 6 + add elif symbol == 'A': i = 4 + add elif symbol == 'B': i = 5 + add else: print('Ты не должен сюда попасть, но вдруг') return self.setFormat(start, ax, stile[i]) self.current_g_cod_pool[self.count][i + 1] = nya.captured(n + 1) def to_the_start(self): self.standart_step = 1 self.count = 0 self.base.progress_bar.setMaximum(1) print("the end1")
class SyntaxHighlighter(QSyntaxHighlighter): """ Syntax highlighter for python """ def __init__(self, parent: QTextDocument = None, *args, **kwargs): super().__init__(parent, *args, **kwargs) # private members self._comment_start_expression = None self._comment_end_expression = None self._keyword_format = QTextCharFormat() self._class_format = QTextCharFormat() self._single_line_comment_format = QTextCharFormat() self._multi_line_comment_format = QTextCharFormat() self._quotation_format = QTextCharFormat() self._function_format = QTextCharFormat() self._highlighting_rules = list() # highlighting rules self._keyword_format.setForeground(Qt.darkBlue) self._keyword_format.setFontWeight(QFont.Bold) keywords = [ 'class', 'def', 'return' 'self', 'float', 'int', 'list', 'dict', 'if', 'else', 'elif', 'pass', 'None', 'object', 'for', 'while', 'is', 'in', 'print', 'round', 'min', 'max', 'abs', 'lambda', 'import', 'as', 'from', 'and', 'or' ] keyword_patterns = ['\\b{}\\b'.format(keyword) for keyword in keywords] for pattern in keyword_patterns: rule = HighlightingRule() rule.pattern = QRegularExpression(pattern) rule.format = self._keyword_format self._highlighting_rules.append(rule) self._class_format.setFontWeight(QFont.Bold) self._class_format.setForeground(Qt.darkMagenta) rule = HighlightingRule() rule.pattern = QRegularExpression('\\bQ[A-Za-z+\\b]') rule.format = self._class_format self._highlighting_rules.append(rule) self._quotation_format.setFontWeight(QFont.Bold) self._quotation_format.setForeground(Qt.darkGreen) rule = HighlightingRule() rule.pattern = QRegularExpression('".*"') rule.format = self._quotation_format self._highlighting_rules.append(rule) rule = HighlightingRule() rule.pattern = QRegularExpression("'.*'") rule.format = self._quotation_format self._highlighting_rules.append(rule) self._function_format.setForeground(Qt.blue) rule = HighlightingRule() rule.pattern = QRegularExpression('\\b[A-Za-z0-9_]+(?=\\())') rule.format = self._function_format self._highlighting_rules.append(rule) self._single_line_comment_format.setForeground(Qt.gray) rule = HighlightingRule() rule.pattern = QRegularExpression('#[^\n]*') rule.format = self._single_line_comment_format self._highlighting_rules.append(rule) self._multi_line_comment_format.setForeground(Qt.gray) self._comment_start_expression = QRegularExpression('"""*') self._comment_end_expression = QRegularExpression('*"""') def highlightBlock(self, p_str): for rule in self._highlighting_rules: match_iterator = rule.pattern.globalMatch(p_str) while match_iterator.hasNext(): match = match_iterator.next() self.setFormat(match.capturedStart(), match.capturedLength(), rule.format) self.setCurrentBlockState(0) start_index = 0 if self.previousBlockState() != 1: start_index = index_in_str( p_str, self._comment_start_expression.pattern()) while start_index >= 0: match = self._comment_end_expression.match(p_str, start_index) end_index = match.capturedStart() comment_length = 0 if end_index == -1: self.setCurrentBlockState(1) comment_length = len(p_str) - start_index else: comment_length = end_index - start_index + match.capturedLength( ) self.setFormat(start_index, comment_length, self._multi_line_comment_format) start_index = index_in_str( p_str, self._comment_start_expression.pattern(), start_index + comment_length)
class PythonHighlighter(QSyntaxHighlighter): KEYWORDS = [ 'False', 'def', 'if', 'raise', 'None', 'del', 'import', 'return', 'True', 'elif', 'in', 'try', 'and', 'else', 'is', 'while', 'as', 'except', 'lambda', 'with', 'assert', 'finally', 'nonlocal', 'yield', 'break', 'for', 'not', 'class', 'from', 'or', 'continue', 'global', 'pass' ] OPERATORS = [ '=', # Comparison '==', '!=', '<', '<=', '>', '>=', # Arithmetic '\+', '-', '\*', '/', '//', '\%', '\*\*', # In-place '\+=', '-=', '\*=', '/=', '\%=', # Bitwise '\^', '\|', '\&', '\~', '>>', '<<', ] BRACES = ['\{', '\}', '\(', '\)', '\[', '\]'] def __init__(self, document): QSyntaxHighlighter.__init__(self, document) rules = [] # These are the defaults rules rules += [(r'\b%s\b' % kw, 0, STYLES["keyword"]) for kw in PythonHighlighter.KEYWORDS] rules += [(r'%s' % o, 0, STYLES["operator"]) for o in PythonHighlighter.OPERATORS] rules += [(r'%s' % b, 0, STYLES["brace"]) for b in PythonHighlighter.BRACES] # All other rules rules += [ # 'self' (r'\bself\b', 0, STYLES['self']), # Double-quoted string, possibly containing escape sequences (r'"[^"\\]*(\\.[^"\\]*)*"', 0, STYLES['string']), # Single-quoted string, possibly containing escape sequences (r"'[^'\\]*(\\.[^'\\]*)*'", 0, STYLES['string']), # 'def' followed by an identifier (r'\bdef\b\s*(\w+)', 1, STYLES['defclass']), # 'class' followed by an identifier (r'\bclass\b\s*(\w+)', 1, STYLES['defclass']), # From '#' until a newline (r'#[^\n]*', 0, STYLES['comment']), # Numeric literals (r'\b[+-]?[0-9]+[lL]?\b', 0, STYLES['numbers']), (r'\b[+-]?0[xX][0-9A-Fa-f]+[lL]?\b', 0, STYLES['numbers']), (r'\b[+-]?[0-9]+(?:\.[0-9]+)?(?:[eE][+-]?[0-9]+)?\b', 0, STYLES['numbers']), ] self.rules = [(QRegExp(pat), index, fmt) for (pat, index, fmt) in rules] self.multiline_end = QRegExp(r'"""') self.multiline_start = QRegExp(r'"""') def highlightBlock(self, text): """Apply highlight""" # expression is a QRegularExpression # Nth is the index of the matched thing for expression, nth, fmt in self.rules: matchIter = expression.globalMatch(text) while matchIter.hasNext(): match = matchIter.next() self.setFormat(match.capturedStart(nth), match.capturedLength(nth), fmt) self.setCurrentBlockState(0) startIndex = 0 if (self.previousBlockState() != 1): startIndex = self.multiline_start.match(text).capturedStart() while (startIndex >= 0): # print(dir(self.multiline_end)) match = self.multiline_end.match(text, startIndex) endIndex = match.capturedStart() commentLength = 0 if (endIndex == -1): self.setCurrentBlockState(1) commentLength = text.length() - startIndex else: commentLength = endIndex - startIndex + match.capturedLength() self.setFormat(startIndex, commentLength, STYLES["string2"]) startIndex = self.multiline_start.match( text, startIndex + commentLength).capturedStart()
class CxxHighlighter(QSyntaxHighlighter): def __init__(self, parent): super().__init__(parent) self.rules = [] keywordFormat = QTextCharFormat() keywordFormat.setForeground(QColor("#0016ba")) keywordFormat.setFontWeight(QFont.Bold) keywordPatterns = [ "\\bchar\\b", "\\bclass\\b", "\\bconst\\b", "\\bdouble\\b", "\\benum\\b", "\\bexplicit\\b", "\\bfriend\\b", "\\binline\\b", "\\bint\\b", "\\blong\\b", "\\bnamespace\\b", "\\boperator\\b", "\\bprivate\\b", "\\bprotected\\b", "\\bpublic\\b", "\\bshort\\b", "\\bsignals\\b", "\\bsigned\\b", "\\bslots\\b", "\\bstatic\\b", "\\bstruct\\b", "\\btemplate\\b", "\\btypedef\\b", "\\btypename\\b", "\\bunion\\b", "\\bunsigned\\b", "\\bvirtual\\b", "\\bvoid\\b", "\\bvolatile\\b", "\\bbool\\b", "\\bchar8_t\\b", "\\bchar16_t\\b", "\\bchar32_t\\b", ] for pattern in keywordPatterns: rule = { 'pattern': QRegularExpression(pattern), 'format': keywordFormat } self.rules.append(rule) keyword2Format = QTextCharFormat() keyword2Format.setForeground(QColor("#0016ba")) keyword2Format.setFontWeight(QFont.Bold) keyword2Patterns = [ "\\balignas\\b", "\\balignof\\b", "\\band\\b", "\\band_eq\\b", "\\basm\\b", "\\batomic_cancel\\b", "\\batomic_commit\\b", "\\batomic_noexcept\\b", "\\bauto\\b", "\\bbitand\\b", "\\bbitor\\b", "\\bbreak\\b", "\\bcase\\b", "\\bcatch\\b", "\\bcompl\\b", "\\bconcept\\b", "\\bconsteval\\b", "\\bconstexpr\\b", "\\bconstinit\\b", "\\bconst_cast\\b", "\\bcontinue\\b", "\\bco_await\\b", "\\bco_return\\b", "\\bco_yield\\b", "\\bdecltype\\b", "\\bdefault\\b", ] for pattern in keyword2Patterns: rule = { 'pattern': QRegularExpression(pattern), 'format': keyword2Format } self.rules.append(rule) classFormat = QTextCharFormat() classFormat.setFontWeight(QFont.Bold) classFormat.setForeground(Qt.darkMagenta) rule = { 'pattern': QRegularExpression("\\bQ[A-Za-z]+\\b"), 'format': classFormat } self.rules.append(rule) quotationFormat = QTextCharFormat() quotationFormat.setForeground(QColor("#c90000")) rule = { 'pattern': QRegularExpression("\".*\""), 'format': quotationFormat } self.rules.append(rule) directiveFormat = QTextCharFormat() directiveFormat.setForeground(QColor("#c95508")) rule = { 'pattern': QRegularExpression("#.*"), 'format': directiveFormat } self.rules.append(rule) stdFormat = QTextCharFormat() stdFormat.setForeground(QColor("#8c8c8c")) rule = { 'pattern': QRegularExpression("std::[A-Za-z]+"), 'format': stdFormat } self.rules.append(rule) # functionFormat = QTextCharFormat() # functionFormat.setForeground(Qt.blue) # rule = {'pattern':QRegularExpression("\\b[A-Za-z0-9_]+(?=\\()"), # 'format':functionFormat} # self.rules.append(rule) singleLineCommentFormat = QTextCharFormat() singleLineCommentFormat.setForeground(Qt.darkGreen) rule = { 'pattern': QRegularExpression("//[^\n]*"), 'format': singleLineCommentFormat } self.rules.append(rule) self.multiLineCommentFormat = QTextCharFormat() self.multiLineCommentFormat.setForeground(Qt.red) self.commentStartExpression = QRegularExpression("/\\*") self.commentEndExpression = QRegularExpression("\\*/") def highlightBlock(self, text): for rule in self.rules: matchIter = rule['pattern'].globalMatch(text) while matchIter.hasNext(): match = matchIter.next() self.setFormat(match.capturedStart(), match.capturedLength(), rule['format']) self.setCurrentBlockState(0) startIdx = 0 if self.previousBlockState() != 1: startIdx = text.find(self.commentStartExpression.pattern()) while startIdx >= 0: match = self.commentEndExpression.match(text, startIdx) endIdx = match.capturedStart() commentLength = 0 if endIdx == -1: self.setCurrentBlockState(1) commentLength = len(text) - startIdx else: commentLength = endIdx - startIdx + match.capturedLength() self.setFormat(startIdx, commentLength, self.multiLineCommentFormat) startIdx = text.find(self.commentStartExpression.pattern(), start=startIdx + commentLength)