码迷,mamicode.com
首页 > 其他好文 > 详细

pyqt颜色字符

时间:2015-02-07 18:50:40      阅读:1355      评论:0      收藏:0      [点我收藏+]

标签:

from PyQt4.QtGui import QPlainTextEdit, QWidget, QVBoxLayout, QApplication, \

                        QFileDialog, QMessageBox, QTextBrowser, QDockWidget, \

                        QMainWindow, QIcon, QHBoxLayout, QPainter, QGraphicsWidget, \

                        QFontMetrics, QFrame, QTextEdit, QTextFormat, \

                        QTextBlockUserData, QColor, QFont, QTextCursor, \

                        QSyntaxHighlighter, QTextCharFormat

from PyQt4.QtCore import QString, SIGNAL as SIG, Qt, QEvent, QVariant,\

                         QRect, QRegExp, QThread

import sys, os, re

from subprocess import Popen, PIPE

 

NUMBER_BAR_COLOR = QColor(180, 215, 140)

 

BRACKET_MATCHED = QColor(‘blue‘)

BRACKET_UNMATCHED = QColor(‘red‘)

 

CURRENT_LINE_HL  = QColor(200, 205, 0, 70)

 

class BracketsInfo:

    def __init__(self, character, position):

        self.character = character

        self.position  = position

 

class TextBlockData(QTextBlockUserData):

    def __init__(self, parent = None):

        super(TextBlockData, self).__init__()

        self.braces = []

        self.valid = False

 

    def insert_brackets_info(self, info):

        self.valid = True

        self.braces.append(info)

 

    def isValid(self):

        return self.valid

 

class LaTeX(QSyntaxHighlighter):

    command = QRegExp(r‘\\(\w+)?‘)

    cmd_fmt = QTextCharFormat()

    cmd_fmt.setForeground(QColor(‘darkRed‘))

 

    comment = QRegExp(r‘%(.*)?‘)

    cmnt_fmt = QTextCharFormat()

    cmnt_fmt.setForeground(QColor(‘gray‘))

    

    keywords = QRegExp(r‘\\begin|\\end|\\label|\\ref|\\(sub)?(sub)?section‘)

    keyword_fmt = QTextCharFormat()

    keyword_fmt.setForeground(QColor(‘red‘))

 

    rules = [(command, cmd_fmt),

             (comment, cmnt_fmt),

             (keywords, keyword_fmt)]

 

    def __init__(self, parent):

        super(LaTeX, self).__init__(parent)

 

    def highlightBlock(self, text):

        braces = QRegExp(‘(\{|\}|\(|\)|\[|\])‘)

        math_delimiters = QRegExp(r‘(\\begin{equation\*?}|‘ +\

                                   r‘\\begin{align\*?}|‘ +\

                                   r‘\\begin{displaymath\*?})‘)

        begin_end = QRegExp(r‘(\\begin{|\\end{|\\ref|\\label)‘)

        block_data = TextBlockData()

 

        index = braces.indexIn(text)

      

        while index >= 0:

            matched_brace = str(braces.capturedTexts()[0])

            info = BracketsInfo(matched_brace, index)

            block_data.insert_brackets_info(info)

            index = braces.indexIn(text, index + 1)

 

        self.setCurrentBlockUserData(block_data)

 

        for regex, fmt in LaTeX.rules:

            start = regex.indexIn(text, 0)

            while start >= 0:

                length = regex.matchedLength()

                self.setFormat(start, length, fmt)

                start = regex.indexIn(text, start + length)

 

        self.setCurrentBlockState(0)

 

class NumberBar(QWidget):

    def __init__(self, parent = None):

        super(NumberBar, self).__init__(parent)

        self.edit = parent

        layout = QVBoxLayout()

        self.setLayout(layout)

        self.edit.blockCountChanged.connect(self.update_width)

        self.edit.updateRequest.connect(self.update_on_scroll)

        self.update_width(‘1‘)

 

    def update_on_scroll(self, rect, scroll):

        if self.isVisible():

            if scroll:

                self.scroll(0, scroll)

            else:

                self.update()

 

    def update_width(self, string):

        width = self.fontMetrics().width(unicode(string)) + 20

        if self.width() != width:

            self.setFixedWidth(width)

 

    def paintEvent(self, event):

        if self.isVisible():

            block = self.edit.firstVisibleBlock()

            height = self.fontMetrics().height()

            number = block.blockNumber()

            painter = QPainter(self)

            painter.fillRect(event.rect(), NUMBER_BAR_COLOR)

            font = painter.font()

 

            current_block = self.edit.textCursor().block().blockNumber() + 1

 

            condition = True

            while block.isValid() and condition:

                block_geometry = self.edit.blockBoundingGeometry(block)

                offset = self.edit.contentOffset()

                block_top = block_geometry.translated(offset).top()

                number += 1

 

                rect = QRect(0, block_top, self.width() - 5, height)

 

                if number == current_block:

                    font.setBold(True)

                else:

                    font.setBold(False)

 

                painter.setFont(font)

                painter.drawText(rect, Qt.AlignRight, ‘%i‘%number)

 

                if block_top > event.rect().bottom():

                    condition = False

 

                block = block.next()

 

            painter.end()

 

class QLaTeXEdit(QWidget):

    def __init__(self, parent = None):

        super(QLaTeXEdit, self).__init__(parent)

        # Editor Widget ...

        self.edit = QPlainTextEdit()

        self.edit.setFrameStyle(QFrame.NoFrame)

        self.extra_selections = []

        # Line Numbers ...

        self.numbers = NumberBar(self.edit)

        # Syntax Highlighter ...

        self.highlighter = LaTeX(self.edit.document())

 

        # Laying out...

        layout = QHBoxLayout()

        layout.setSpacing(1.5)

        layout.addWidget(self.numbers)

        layout.addWidget(self.edit)

        self.setLayout(layout)

        # Event Filter ...

        self.installEventFilter(self)

        self.edit.cursorPositionChanged.connect(self.check_brackets)

        

        # Brackets ExtraSelection ...

        self.left_selected_bracket  = QTextEdit.ExtraSelection()

        self.right_selected_bracket = QTextEdit.ExtraSelection()

 

    def set_numbers_visible(self, value = True):

        self.numbers.setVisible(False)

 

    def match_left(self, block, character, start, found):

        map = {‘{‘: ‘}‘, ‘(‘: ‘)‘, ‘[‘: ‘]‘}

 

        while block.isValid():

            data = block.userData()

            if data is not None:

                braces = data.braces

                N = len(braces)

 

                for k in range(start, N):

                    if braces[k].character == character:

                        found += 1

 

                    if braces[k].character == map[character]:

                        if not found:

                            return braces[k].position + block.position()

                        else:

                            found -= 1

 

                block = block.next()

                start = 0

 

    def match_right(self, block, character, start, found):

        map = {‘}‘: ‘{‘, ‘)‘: ‘(‘, ‘]‘: ‘[‘}

        

        while block.isValid():

            data = block.userData()

 

            if data is not None:

                braces = data.braces

                

                if start is None:

                    start = len(braces)

                for k in range(start - 1, -1, -1):

                    if braces[k].character == character:

                        found += 1

                    if braces[k].character == map[character]:

                        if found == 0:

                            return braces[k].position + block.position()

                        else:

                            found -= 1

            block = block.previous()

            start = None

 

    def check_brackets(self):

        left, right = QTextEdit.ExtraSelection(),\

                      QTextEdit.ExtraSelection()

 

        cursor = self.edit.textCursor()

        block = cursor.block()

        data = block.userData()

        previous, next = None, None

 

        if data is not None:

            position = cursor.position()

            block_position = cursor.block().position()

            braces = data.braces

            N = len(braces)

 

            for k in range(0, N):

                if braces[k].position == position - block_position or\

                   braces[k].position == position - block_position - 1:

                    previous = braces[k].position + block_position

                    if braces[k].character in [‘{‘, ‘(‘, ‘[‘]:

                        next = self.match_left(block,

                                               braces[k].character,

                                               k + 1, 0)

                    elif braces[k].character in [‘}‘, ‘)‘, ‘]‘]:

                        next = self.match_right(block,

                                                braces[k].character,

                                                k, 0)

                    if next is None:

                        next = -1

 

        if next is not None and next > 0:

            if next == 0 and next >= 0:

                format = QTextCharFormat()

 

                cursor.setPosition(previous)

                cursor.movePosition(QTextCursor.NextCharacter,

                                    QTextCursor.KeepAnchor)

                

                format.setForeground(BRACKET_MATCHED)

                format.setBackground(QColor(‘white‘))

                self.left_selected_bracket.format = format

                self.left_selected_bracket.cursor = cursor

 

                cursor.setPosition(next)

                cursor.movePosition(QTextCursor.NextCharacter,

                                    QTextCursor.KeepAnchor)

                

                format.setForeground(BRACKET_MATCHED)

                format.setBackground(QColor(‘white‘))

                self.right_selected_bracket.format = format

                self.right_selected_bracket.cursor = cursor

 

    def paintEvent(self, event):

        highlighted_line = QTextEdit.ExtraSelection()

        highlighted_line.format.setBackground(CURRENT_LINE_HL)

        highlighted_line.format.setProperty(QTextFormat\

                                                 .FullWidthSelection,

                                                  QVariant(True))

        highlighted_line.cursor = self.edit.textCursor()

        highlighted_line.cursor.clearSelection()

        self.edit.setExtraSelections([highlighted_line,

                                      self.left_selected_bracket,

                                      self.right_selected_bracket])

 

    def document(self):

        return self.edit.document

 

    def getPlainText(self):

        return unicode(self.edit.toPlainText())

 

    def isModified(self):

        return self.edit.document().isModified()

 

    def setModified(self, modified):

        self.edit.document().setModified(modified)

 

    def setLineWrapMode(self, mode):

        self.edit.setLineWrapMode(mode)

 

    def clear(self):

        self.edit.clear()

 

    def setPlainText(self, *args, **kwargs):

        self.edit.setPlainText(*args, **kwargs)

 

    def setDocumentTitle(self, *args, **kwargs):

        self.edit.setDocumentTitle(*args, **kwargs)

 

    def eventFilter(self, object, event):

        if event.type() == QEvent.KeyPress:

            if event.key() == Qt.Key_Return:

                QPlainTextEdit.event(self, event)

                print ‘return pressed‘

                return True

            if event.key() == Qt.Key_F6:

                self.emit(SIG(‘pdflatex‘))

                return True

            if event.key() == Qt.Key_F7:

                self.emit(SIG(‘pdfshow‘))

                return True

            if event.key() == Qt.Key_S and\

               event.modifiers() == Qt.ControlModifier:

                self.emit(SIG(‘save_document‘))

                return True

            if event.key() == Qt.Key_O and\

               event.modifiers() == Qt.ControlModifier:

                self.emit(SIG(‘open_document‘))

                return True

            if event.key() == Qt.Key_N and\

               event.modifiers() == Qt.ControlModifier:

                self.emit(SIG(‘new_document‘))

                return True

            if event.key() == Qt.Key_W and\

               event.modifiers() == Qt.ControlModifier:

                self.emit(SIG(‘close_document‘))

                return True

            else:

                return False

        return False

 

    def set_number_bar_visible(self, value):

        self.numbers.setVisible(value)

 

if __name__ == ‘__main__‘:

    app = QApplication(sys.argv)

    win = QLaTeXEdit()

    win.show()

    app.exec_()

 技术分享

pyqt颜色字符

标签:

原文地址:http://www.cnblogs.com/mhxy13867806343/p/4279154.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!