2016-10-20 6 views
1

私の問題では、stackoverflowを使用して答えを見つけるのは初めてのことです。 私はQtGui.QTextEditを使用して、以下のようなテキストを表示していて、特定のテキストが含まれているかどうかに基づいて、いくつかの行のテキストの色を変更したいとします。QtGui.QTextEdit行の色に行のテキストが含まれているかどうかを確認する

- で始まる行は青色で、[ERROR]を含む行は赤色になります。 私は現在、次のようなもの、

from PyQt4 import QtCore, QtGui, uic 
import sys 

class Log(QtGui.QWidget): 
    def __init__(self, path=None, parent=None): 
     QtGui.QMainWindow.__init__(self, parent) 
     self.taskLog = QtGui.QTextEdit() 
     self.taskLog.setLineWrapMode(False) 
     vbox = QtGui.QVBoxLayout() 
     vbox.addWidget(self.taskLog) 
     self.setLayout(vbox) 

     log = open("/net/test.log", 'r') 
     self.taskLog.setText(log.read()) 
     log.close() 


app = QtGui.QApplication(sys.argv) 
wnd = Log() 
wnd.show() 
sys.exit(app.exec_()) 

は、テキストは、現時点では次のようになりますしている

--[ Begin 
this is a test 

[ERROR] this test failed. 

--[ Command returned exit code 1 

うまくいけば、すべてがしようと、私はたくさんより速く、これをうまく助けることができるようになります私の自己からそれを働かせる。

おかげで、 マーク

答えて

1

QSyntaxHighlighterでこれを簡単に行うことができます。

screenshot

from PyQt4 import QtCore, QtGui 

sample = """ 
--[ Begin 
this is a test 

[ERROR] this test failed. 

--[ Command returned exit code 1 
""" 

class Highlighter(QtGui.QSyntaxHighlighter): 
    def __init__(self, parent): 
     super(Highlighter, self).__init__(parent) 
     self.sectionFormat = QtGui.QTextCharFormat() 
     self.sectionFormat.setForeground(QtCore.Qt.blue) 
     self.errorFormat = QtGui.QTextCharFormat() 
     self.errorFormat.setForeground(QtCore.Qt.red) 

    def highlightBlock(self, text): 
     # uncomment this line for Python2 
     # text = unicode(text) 
     if text.startswith('--['): 
      self.setFormat(0, len(text), self.sectionFormat) 
     elif text.startswith('[ERROR]'): 
      self.setFormat(0, len(text), self.errorFormat) 

class Window(QtGui.QWidget): 
    def __init__(self): 
     super(Window, self).__init__() 
     self.editor = QtGui.QTextEdit(self) 
     self.highlighter = Highlighter(self.editor.document()) 
     self.editor.setText(sample) 
     layout = QtGui.QVBoxLayout(self) 
     layout.addWidget(self.editor) 

if __name__ == '__main__': 

    import sys 
    app = QtGui.QApplication(sys.argv) 
    window = Window() 
    window.setGeometry(500, 150, 300, 300) 
    window.show() 
    sys.exit(app.exec_()) 
+0

こんにちはekhumoro、 これは私が探しているもののよう、それを行うための簡単な方法のように見えますが、次のエラーを取得: トレースバック(最も簡単なデモです( ' - ' '): text.startswith(' - ['): の属性ファイルに' startswith '属性がありません – Mark

+0

startswithを置き換えようとしました正規表現と同様に: デフhighlightBlock(自己、テキスト): - 開始する場合 \t誤差= re.compile(R '^ [ERROR]') \t \tインポート再 \tは= re.compile(R '[^')を開始します.search(テキスト)なしではない: \t \t self.setFormat(0、LEN: \t \t self.setFormat(0、LEN(テキスト)、self.sectionFormat) \t ELIFのerror.search(テキスト)なしではありません(テキスト)、self.errorFormat) – Mark

+0

私に次のエラーを与えるもの トレースバック(最新のコール最後): ファイル"test.py"、23行目、highlightBlock begin = re.compile(r '^ - [') ファイル "/usr/lib64/python2.6/re.py"、190行目、コンパイル リターン_compile(パターン、フラグ) ファイル "/usr/lib64/python2.6/re。py "、行245、_compile エラーを発生します。v#無効な式です。 sre_constants.error:予期しない正規表現 – Mark

0
あなたは、この使用してHTML形式

textEdit.setHtml(text); 
しかし、より良い、QSyntaxHighlighterクラスを達成することができます

ドク:http://doc.qt.io/qt-5/qsyntaxhighlighter.html

PythonのExemple:https://wiki.python.org/moin/PyQt/Python%20syntax%20highlighting

ここでは、コードエディタの例を示します。

import sys 

from PyQt4.QtCore import QRegExp 
from PyQt4.QtGui import QColor, QTextCharFormat, QFont, QSyntaxHighlighter 

def format(color, style=''): 
    """Return a QTextCharFormat with the given attributes. 
    """ 
    _color = QColor() 
    _color.setNamedColor(color) 

    _format = QTextCharFormat() 
    _format.setForeground(_color) 
    if 'bold' in style: 
     _format.setFontWeight(QFont.Bold) 
    if 'italic' in style: 
     _format.setFontItalic(True) 

    return _format 


# Syntax styles that can be shared by all languages 
STYLES = { 
    'keyword': format('blue'), 
    'operator': format('red'), 
    'brace': format('darkGray'), 
    'defclass': format('black', 'bold'), 
    'string': format('magenta'), 
    'string2': format('darkMagenta'), 
    'comment': format('darkGreen', 'italic'), 
    'self': format('black', 'italic'), 
    'numbers': format('brown'), 
} 


class PythonHighlighter (QSyntaxHighlighter): 
    """Syntax highlighter for the Python language. 
    """ 
    # Python keywords 
    keywords = [ 
     'and', 'assert', 'break', 'class', 'continue', 'def', 
     'del', 'elif', 'else', 'except', 'exec', 'finally', 
     'for', 'from', 'global', 'if', 'import', 'in', 
     'is', 'lambda', 'not', 'or', 'pass', 'print', 
     'raise', 'return', 'try', 'while', 'yield', 
     'None', 'True', 'False', 
    ] 

    # Python operators 
    operators = [ 
     '=', 
     # Comparison 
     '==', '!=', '<', '<=', '>', '>=', 
     # Arithmetic 
     '\+', '-', '\*', '/', '//', '\%', '\*\*', 
     # In-place 
     '\+=', '-=', '\*=', '/=', '\%=', 
     # Bitwise 
     '\^', '\|', '\&', '\~', '>>', '<<', 
    ] 

    # Python braces 
    braces = [ 
     '\{', '\}', '\(', '\)', '\[', '\]', 
    ] 
    def __init__(self, document): 
     QSyntaxHighlighter.__init__(self, document) 

     # Multi-line strings (expression, flag, style) 
     # FIXME: The triple-quotes in these two lines will mess up the 
     # syntax highlighting from this point onward 
     self.tri_single = (QRegExp("'''"), 1, STYLES['string2']) 
     self.tri_double = (QRegExp('"""'), 2, STYLES['string2']) 

     rules = [] 

     # Keyword, operator, and brace rules 
     rules += [(r'\b%s\b' % w, 0, STYLES['keyword']) 
      for w 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']), 
     ] 

     # Build a QRegExp for each pattern 
     self.rules = [(QRegExp(pat), index, fmt) 
      for (pat, index, fmt) in rules] 


    def highlightBlock(self, text): 
     """Apply syntax highlighting to the given block of text. 
     """ 
     # Do other syntax formatting 
     for expression, nth, format in self.rules: 
      index = expression.indexIn(text, 0) 

      while index >= 0: 
       # We actually want the index of the nth match 
       index = expression.pos(nth) 
       length = expression.cap(nth).length() 
       self.setFormat(index, length, format) 
       index = expression.indexIn(text, index + length) 

     self.setCurrentBlockState(0) 

     # Do multi-line strings 
     in_multiline = self.match_multiline(text, *self.tri_single) 
     if not in_multiline: 
      in_multiline = self.match_multiline(text, *self.tri_double) 


    def match_multiline(self, text, delimiter, in_state, style): 
     """Do highlighting of multi-line strings. ``delimiter`` should be a 
     ``QRegExp`` for triple-single-quotes or triple-double-quotes, and 
     ``in_state`` should be a unique integer to represent the corresponding 
     state changes when inside those strings. Returns True if we're still 
     inside a multi-line string when this function is finished. 
     """ 
     # If inside triple-single quotes, start at 0 
     if self.previousBlockState() == in_state: 
      start = 0 
      add = 0 
     # Otherwise, look for the delimiter on this line 
     else: 
      start = delimiter.indexIn(text) 
      # Move past this match 
      add = delimiter.matchedLength() 

     # As long as there's a delimiter match on this line... 
     while start >= 0: 
      # Look for the ending delimiter 
      end = delimiter.indexIn(text, start + add) 
      # Ending delimiter on this line? 
      if end >= add: 
       length = end - start + add + delimiter.matchedLength() 
       self.setCurrentBlockState(0) 
      # No; multi-line string 
      else: 
       self.setCurrentBlockState(in_state) 
       length = text.length() - start + add 
      # Apply formatting 
      self.setFormat(start, length, style) 
      # Look for the next match 
      start = delimiter.indexIn(text, start + length) 

     # Return True if still inside a multi-line string, False otherwise 
     if self.currentBlockState() == in_state: 
      return True 
     else: 
      return False 
関連する問題