aboutsummaryrefslogtreecommitdiffstats
path: root/examples/widgets/richtext/textobject/textobject.py
blob: cfd065e22118dbbaebcf2b904cfb76b8b8f4a780 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# Copyright (C) 2013 Riverbank Computing Limited.
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause

"""PySide6 port of the widgets/richtext/textobject example from Qt v5.x"""

import os
from pathlib import Path
import sys

from PySide6.QtCore import QFile, QIODevice, QObject, QSizeF, Qt, Slot
from PySide6.QtGui import (QTextCharFormat, QTextFormat, QTextObjectInterface,
                           QPyTextObject)
from PySide6.QtWidgets import (QApplication, QHBoxLayout, QLabel, QLineEdit,
                               QMessageBox, QPushButton, QTextEdit,
                               QVBoxLayout, QWidget)
from PySide6.QtSvg import QSvgRenderer


SVG_TEXT_FORMAT = QTextFormat.UserObject + 1


SVG_DATA = 1


class SvgTextObject(QPyTextObject):
    def __init__(self, parent=None):
        super().__init__(parent)

    def intrinsicSize(self, doc, posInDocument, format):
        renderer = QSvgRenderer(format.property(SVG_DATA))
        size = renderer.defaultSize()

        if size.height() > 25:
            size *= 25.0 / size.height()

        return QSizeF(size)

    def drawObject(self, painter, rect, doc, posInDocument, format):
        renderer = QSvgRenderer(format.property(SVG_DATA))
        renderer.render(painter, rect)


class Window(QWidget):

    def __init__(self):
        super().__init__()

        self.setup_gui()
        self.setup_text_object()

        self.setWindowTitle(self.tr("Text Object Example"))

    @Slot()
    def insert_text_object(self):
        file_name = self._file_name_line_edit.text()
        file = QFile(file_name)

        if not file.open(QIODevice.ReadOnly):
            reason = file.errorString()
            message = f"Could not open '{file_name}': {reason}"
            QMessageBox.warning(self, "Error Opening File", message)

        svg_data = file.readAll()

        svg_char_format = QTextCharFormat()
        svg_char_format.setObjectType(SVG_TEXT_FORMAT)
        svg_char_format.setProperty(SVG_DATA, svg_data)

        cursor = self._text_edit.textCursor()
        cursor.insertText(chr(0xfffc), svg_char_format)
        self._text_edit.setTextCursor(cursor)

    def setup_text_object(self):
        svg_interface = SvgTextObject(self)
        doc_layout = self._text_edit.document().documentLayout()
        doc_layout.registerHandler(SVG_TEXT_FORMAT, svg_interface)

    def setup_gui(self):
        file_name_label = QLabel(self.tr("Svg File Name:"))
        self._file_name_line_edit = QLineEdit()
        self._file_name_line_edit.setClearButtonEnabled(True)
        insert_text_object_button = QPushButton(self.tr("Insert Image"))

        file = os.fspath(Path(__file__).resolve().parent / 'files' / 'heart.svg')
        self._file_name_line_edit.setText(file)
        insert_text_object_button.clicked.connect(self.insert_text_object)

        bottom_layout = QHBoxLayout()
        bottom_layout.addWidget(file_name_label)
        bottom_layout.addWidget(self._file_name_line_edit)
        bottom_layout.addWidget(insert_text_object_button)

        self._text_edit = QTextEdit()

        main_layout = QVBoxLayout(self)
        main_layout.addWidget(self._text_edit)
        main_layout.addLayout(bottom_layout)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = Window()
    window.show()
    sys.exit(app.exec())