"""A simple text window used to display either Python code with some simple syntax highlighting, or some other document which will be formatted as though it was an html file or a simple text file. The syntax highlighter for Python code is really inadequate; HELP!! :-) """ try: from PyQt4 import QtGui, QtCore qt_widgets = QtGui except ImportError: from PyQt5 import QtCore, QtGui from PyQt5 import QtWidgets as qt_widgets import keyword import sys if sys.version_info < (3,): from cStringIO import StringIO else: from io import StringIO class TextWindow(qt_widgets.QMainWindow): def __init__(self, file_name=None, title="Title", text_type='text', text='Default text'): """Simple text window whose input comes from a file, if a file_name is specified, or from a supplied string. text_type can be one of 4 values: 'text', 'code', 'html', 'python'. If 'python' is specified, some basic syntax highlighting is added. """ super(TextWindow, self).__init__(None) self.setWindowTitle(title) self.resize(900, 600) self.editor = qt_widgets.QTextEdit(self) self.setCentralWidget(self.editor) self.editor.setFocus() if file_name is not None: text = self.load(file_name) if text_type == 'text' or text_type == 'html': self.set_text_font() elif text_type == 'code': self.set_monospace_font() elif text_type == 'python': self.set_monospace_font() self.highlighter = Highlighter(self.editor.document()) else: self.set_text_font() text = "Unknown text_type: {}".format(text_type) if text_type == 'html': self.editor.setHtml(text) else: self.editor.setPlainText(text) def set_text_font(self): font = QtGui.QFont() font.setFamily('Arial') font.setFixedPitch(False) font.setPointSize(12) self.editor.setFont(font) def set_monospace_font(self): font = QtGui.QFont() font.setFamily('Courier') font.setFixedPitch(True) font.setPointSize(12) self.editor.setFont(font) def load(self, f): if not QtCore.QFile.exists(f): self.text_type = 'text' return "File %s could not be found." % f try: file_handle = QtCore.QFile(f) file_handle.open(QtCore.QFile.ReadOnly) data = file_handle.readAll() codec = QtCore.QTextCodec.codecForHtml(data) return codec.toUnicode(data) except: self.text_type = 'text' return 'Problem reading file %s' % f class Highlighter(QtGui.QSyntaxHighlighter): """Adapted from example included with PyQt distribution""" def __init__(self, parent=None): super(Highlighter, self).__init__(parent) keywordFormat = QtGui.QTextCharFormat() keywordFormat.setForeground(QtCore.Qt.blue) keywordFormat.setFontWeight(QtGui.QFont.Bold) keywordPatterns = ["\\b{}\\b".format(k) for k in keyword.kwlist] self.highlightingRules = [(QtCore.QRegExp(pattern), keywordFormat) for pattern in keywordPatterns] classFormat = QtGui.QTextCharFormat() classFormat.setFontWeight(QtGui.QFont.Bold) self.highlightingRules.append((QtCore.QRegExp("\\bQ[A-Za-z]+\\b"), classFormat)) singleLineCommentFormat = QtGui.QTextCharFormat() singleLineCommentFormat.setForeground(QtCore.Qt.gray) self.highlightingRules.append((QtCore.QRegExp("#[^\n]*"), singleLineCommentFormat)) quotationFormat = QtGui.QTextCharFormat() quotationFormat.setForeground(QtCore.Qt.darkGreen) self.highlightingRules.append((QtCore.QRegExp("\".*\""), quotationFormat)) self.highlightingRules.append((QtCore.QRegExp("'.*'"), quotationFormat)) def highlightBlock(self, text): for pattern, format in self.highlightingRules: expression = QtCore.QRegExp(pattern) index = expression.indexIn(text) while index >= 0: length = expression.matchedLength() self.setFormat(index, length, format) index = expression.indexIn(text, index + length) self.setCurrentBlockState(0) if __name__ == '__main__': app = qt_widgets.QApplication([]) editor1 = TextWindow(file_name="../README.rst", title="Demo of text file", text_type = 'text') editor1.move(10, 10) editor1.show() editor2 = TextWindow(file_name = "readme.html", title="Demo of html file", text_type="html") editor2.move(840, 10) editor2.show() editor3 = TextWindow(title="Demo of Python file", file_name=__file__, text_type='python') editor3.move(440, 410) editor3.show() editor4 = TextWindow(file_name="../README.rst", title="Demo of unknown test_type", text_type = 'unknown') editor4.show() sys.exit(app.exec_())