aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCristian Maureira-Fredes <cristian.maureira-fredes@qt.io>2019-01-28 13:33:55 +0100
committerCristian Maureira-Fredes <cristian.maureira-fredes@qt.io>2019-01-30 13:30:09 +0000
commit857b1954051b6d04387958ea005413c51417056e (patch)
treebd5c5b8ed8e3c217e348d70646c0035d5fef90c2
parent34e6ac44ef6d322760fcda02136b25a097b0fe15 (diff)
Add codeeditor example
Based on Qt's Code Editor example Change-Id: I17ba0dfbafcda5a599cd2ef051e842cdd4b6e305 Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
-rw-r--r--examples/widgets/codeeditor/codeeditor.py141
-rw-r--r--examples/widgets/codeeditor/main.py52
2 files changed, 193 insertions, 0 deletions
diff --git a/examples/widgets/codeeditor/codeeditor.py b/examples/widgets/codeeditor/codeeditor.py
new file mode 100644
index 000000000..331069f4a
--- /dev/null
+++ b/examples/widgets/codeeditor/codeeditor.py
@@ -0,0 +1,141 @@
+#############################################################################
+##
+## Copyright (C) 2019 The Qt Company Ltd.
+## Contact: http://www.qt.io/licensing/
+##
+## This file is part of the Qt for Python examples of the Qt Toolkit.
+##
+## $QT_BEGIN_LICENSE:BSD$
+## You may use this file under the terms of the BSD license as follows:
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are
+## met:
+## * Redistributions of source code must retain the above copyright
+## notice, this list of conditions and the following disclaimer.
+## * Redistributions in binary form must reproduce the above copyright
+## notice, this list of conditions and the following disclaimer in
+## the documentation and/or other materials provided with the
+## distribution.
+## * Neither the name of The Qt Company Ltd nor the names of its
+## contributors may be used to endorse or promote products derived
+## from this software without specific prior written permission.
+##
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+from PySide2.QtCore import Slot, Qt, QRect, QSize
+from PySide2.QtGui import QColor, QPainter, QTextFormat
+from PySide2.QtWidgets import QPlainTextEdit, QWidget, QTextEdit
+
+
+class LineNumberArea(QWidget):
+ def __init__(self, editor):
+ QWidget.__init__(self, editor)
+ self.codeEditor = editor
+
+ def sizeHint(self):
+ return QSize(self.codeEditor.line_number_area_width(), 0)
+
+ def paintEvent(self, event):
+ self.codeEditor.lineNumberAreaPaintEvent(event)
+
+
+class CodeEditor(QPlainTextEdit):
+ def __init__(self):
+ QPlainTextEdit.__init__(self)
+ self.line_number_area = LineNumberArea(self)
+
+ self.blockCountChanged[int].connect(self.update_line_number_area_width)
+ self.updateRequest[QRect, int].connect(self.update_line_number_area)
+ self.cursorPositionChanged.connect(self.highlight_current_line)
+
+ self.update_line_number_area_width(0)
+ self.highlight_current_line()
+
+ def line_number_area_width(self):
+ digits = 1
+ max_num = max(1, self.blockCount())
+ while max_num >= 10:
+ max_num *= 0.1
+ digits += 1
+
+ space = 3 + self.fontMetrics().width('9') * digits
+ return space
+
+ def resizeEvent(self, e):
+ super().resizeEvent(e)
+ cr = self.contentsRect()
+ width = self.line_number_area_width()
+ rect = QRect(cr.left(), cr.top(), width, cr.height())
+ self.line_number_area.setGeometry(rect)
+
+ def lineNumberAreaPaintEvent(self, event):
+ painter = QPainter(self.line_number_area)
+ painter.fillRect(event.rect(), Qt.lightGray)
+ block = self.firstVisibleBlock()
+ block_number = block.blockNumber()
+ offset = self.contentOffset()
+ top = self.blockBoundingGeometry(block).translated(offset).top()
+ bottom = top + self.blockBoundingRect(block).height()
+
+ while block.isValid() and top <= event.rect().bottom():
+ if block.isVisible() and bottom >= event.rect().top():
+ number = str(block_number + 1)
+ painter.setPen(Qt.black)
+ width = self.line_number_area.width()
+ height = self.fontMetrics().height()
+ painter.drawText(0, top, width, height, Qt.AlignRight, number)
+
+ block = block.next()
+ top = bottom
+ bottom = top + self.blockBoundingRect(block).height()
+ block_number += 1
+
+ @Slot()
+ def update_line_number_area_width(self, newBlockCount):
+ self.setViewportMargins(self.line_number_area_width(), 0, 0, 0)
+
+ @Slot()
+ def update_line_number_area(self, rect, dy):
+ if dy:
+ self.line_number_area.scroll(0, dy)
+ else:
+ width = self.line_number_area.width()
+ self.line_number_area.update(0, rect.y(), width, rect.height())
+
+ if rect.contains(self.viewport().rect()):
+ self.update_line_number_area_width(0)
+
+ @Slot()
+ def highlight_current_line(self):
+ extra_selections = []
+
+ if not self.isReadOnly():
+ selection = QTextEdit.ExtraSelection()
+
+ line_color = QColor(Qt.yellow).lighter(160)
+ selection.format.setBackground(line_color)
+
+ selection.format.setProperty(QTextFormat.FullWidthSelection, True)
+
+ selection.cursor = self.textCursor()
+ selection.cursor.clearSelection()
+
+ extra_selections.append(selection)
+
+ self.setExtraSelections(extra_selections)
diff --git a/examples/widgets/codeeditor/main.py b/examples/widgets/codeeditor/main.py
new file mode 100644
index 000000000..14c2e0826
--- /dev/null
+++ b/examples/widgets/codeeditor/main.py
@@ -0,0 +1,52 @@
+#############################################################################
+##
+## Copyright (C) 2019 The Qt Company Ltd.
+## Contact: http://www.qt.io/licensing/
+##
+## This file is part of the Qt for Python examples of the Qt Toolkit.
+##
+## $QT_BEGIN_LICENSE:BSD$
+## You may use this file under the terms of the BSD license as follows:
+##
+## "Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions are
+## met:
+## * Redistributions of source code must retain the above copyright
+## notice, this list of conditions and the following disclaimer.
+## * Redistributions in binary form must reproduce the above copyright
+## notice, this list of conditions and the following disclaimer in
+## the documentation and/or other materials provided with the
+## distribution.
+## * Neither the name of The Qt Company Ltd nor the names of its
+## contributors may be used to endorse or promote products derived
+## from this software without specific prior written permission.
+##
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+import sys
+from PySide2.QtWidgets import QApplication
+from codeeditor import CodeEditor
+
+"""PySide2 port of the widgets/codeeditor example from Qt5"""
+
+if __name__ == "__main__":
+ app = QApplication([])
+ editor = CodeEditor()
+ editor.setWindowTitle("Code Editor Example")
+ editor.show()
+ sys.exit(app.exec_())