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颜色字符的更多相关文章
-
Linux Shell输出颜色字符学习笔记(附Python脚本实现自动化定制生成)
齿轮发出咔嚓一声,向前进了一格.而一旦向前迈进,齿轮就不能倒退了.这就是世界的规则. 0x01背景 造了个*:御剑师傅的ipintervalmerge的Python版本.觉得打印的提示信息如果是普通 ...
-
python - 2 8 16进制/颜色/字符编码
1.二进制 八进制 十六进制 二进制: bin() 0b10010八进制: oct() 0o10十进制: 1-100十六进制: hex() 0X53 BH 十进制转2, 8,16进制: >> ...
-
显示log里的ansi codecs颜色字符
方法: vim AnsiEsc插件 http://www.vim.org/scripts/script.php?script_id=302 less -r cat和tail命令都可以正常显示,而且ta ...
-
[转载]Linux下终端字体颜色设置方法
原文地址:Linux下终端字体颜色设置方法作者:router 网上类似的文章有很多,但是都是转来转去的,没有经过测试,按照很多文章的方法会造成你设置之后的终端在换行和删除输入字符时终端显示会乱七八糟, ...
-
Markdown文字添加颜色
转自:原文地址 添加红色 效果: 写法: $\color{red}{red}$ 添加绿色 效果: 写法: $\color{green}{green}$ 添加蓝色 效果: 写法: $\color{blu ...
-
Linux字符界面字符颜色显示
一.字符颜色 #!/bin/bash #字符颜色显示 #-e:允许echo使用转义 #\033[:开始位 #\033[0m:结束位 #\033等同于\e echo -e "\033[30m黑 ...
-
【canvas学习笔记三】样式和颜色
上一节我们学习了如何用路径绘制各种形状,但我们只能用默认的颜色和线条.这节就来学习设置不同的颜色和线条样式. 颜色 设置颜色主要有两个属性: fillStyle = color 设置填充颜色 stro ...
-
HTML 学习笔记 CSS样式(文本)
CSS文本属性可以定义文本的外观 通过文本属性 您可以改变文本的颜色 字符间距 文本对齐装饰文本 对文本进行缩进等等. 缩进文本 把web页面上的段落的第一行缩进,这是最常用的文本格式化效果. css ...
-
qt_文本编辑器实现_附带详细注释和源码下载
源码下载: 链接: http://pan.baidu.com/s/1c21EVRy 密码: qub8 实现主要的功能有:新建,打开,保存,另存为,查找(查找的时候需要先将光标放到最下面位置才能查全,不 ...
随机推荐
-
Linux 环境变量 设置 etc profile
一.Linux的变量种类 按变量的生存周期来划分,Linux变量可分为两类: 1.永久的:需要修改配置文件,变量永久生效. 2.临时的:使用export命令声明即可,变量在关闭shell时失效. 二. ...
-
scala pattern matching
scala语言的一大重要特性之一就是模式匹配.在我看来,这个怎么看都很像java语言中的switch语句,但是,这个仅仅只是像(因为有case关键字),他们毕竟是不同的东西,switch在java中, ...
-
JQUERY与JS的区别
JQUERY与JS的区别 <style type="text/css"> #aa { width:200px; height:200px; } </style&g ...
-
python获取每颗cpu使用率
以下是关于python来获取服务器每颗CPU使用率的使用脚本. #!/usr/bin/env python # -*- coding: utf-8 -*- import re,time def _re ...
-
Nodejs微信接口
代码重要部分都已详细注释,test.js为实例,如果启动url请求,那么程序默认对json格式数据友好,如果有特殊需要,请自行修改返回数据的处理格式 大概功能简介为下: this._token 提供t ...
-
网站HTTP请求过程解析
网站性能优化中首要的一条就是要减少HTTP请求,那么为要减少HTTP请求呢?其实有些HTTP分析工具可以帮我们了解当浏览器请求一个资源时大致需要经历的哪些过程: 1 域名解析(DNS Lookup): ...
-
Uva 10142 Australia Voting
水题 模拟 大意就是模拟一个选举的系统 认真读题,注意细节,耐心调试 #include<cmath> #include<math.h> #include<ctype.h& ...
-
Maven简介(一)
在现实的企业中,以低成本.高效率.高质量的完成项目,不仅仅需要技术大牛,企业更加需要管理大牛,管理者只懂技术是远远不够的.当然,管理可以说有很多的方面,例如:对人员的管理,也有对项目的管理等等.如果你 ...
-
[Swift]LeetCode763. 划分字母区间 | Partition Labels
A string S of lowercase letters is given. We want to partition this string into as many parts as pos ...
-
手机端-万种bt在线观看器,安卓正版下载
安卓正版下载, 点击下载 无广告,完全免费!寻找任何你想要的资源!