QT-PyQt-PySide-Custom-Widgets-Pro 1.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- custom_widgets_pro/__init__.py +73 -0
- custom_widgets_pro/_catalog.py +25 -0
- custom_widgets_pro/_cli.py +132 -0
- custom_widgets_pro/_license.py +419 -0
- custom_widgets_pro/_version.py +14 -0
- custom_widgets_pro/datatable/__init__.py +17 -0
- custom_widgets_pro/datatable/datatable_pro.py +319 -0
- custom_widgets_pro/datatable/export.py +143 -0
- custom_widgets_pro/datatable/frozen_view.py +112 -0
- custom_widgets_pro/datatable/grouping.py +309 -0
- custom_widgets_pro/datatable/pivot.py +100 -0
- custom_widgets_pro/datatable/provider.py +98 -0
- custom_widgets_pro/datatable/virtual_model.py +451 -0
- custom_widgets_pro/widgets/__init__.py +7 -0
- custom_widgets_pro/widgets/charts/QCustomBeeswarm.py +317 -0
- custom_widgets_pro/widgets/charts/QCustomBubbleChart.py +655 -0
- custom_widgets_pro/widgets/charts/QCustomCandlestickChart.py +522 -0
- custom_widgets_pro/widgets/charts/QCustomDivergingBarChart.py +430 -0
- custom_widgets_pro/widgets/charts/QCustomDotMatrix.py +266 -0
- custom_widgets_pro/widgets/charts/QCustomFunnelChart.py +474 -0
- custom_widgets_pro/widgets/charts/QCustomGanttChart.py +376 -0
- custom_widgets_pro/widgets/charts/QCustomHeatmap.py +555 -0
- custom_widgets_pro/widgets/charts/QCustomRadarChart.py +600 -0
- custom_widgets_pro/widgets/charts/QCustomRadialBars.py +441 -0
- custom_widgets_pro/widgets/charts/QCustomRadialLines.py +554 -0
- custom_widgets_pro/widgets/charts/QCustomRangeBarChart.py +504 -0
- custom_widgets_pro/widgets/charts/QCustomSankey.py +539 -0
- custom_widgets_pro/widgets/charts/QCustomScatterChart.py +623 -0
- custom_widgets_pro/widgets/charts/__init__.py +1 -0
- custom_widgets_pro/widgets/data/QCustomCodeEditor.py +391 -0
- custom_widgets_pro/widgets/data/QCustomNodeGraph.py +1030 -0
- custom_widgets_pro/widgets/data/QCustomRichTextEditor.py +189 -0
- custom_widgets_pro/widgets/data/QCustomTableToolbar.py +566 -0
- custom_widgets_pro/widgets/data/__init__.py +1 -0
- custom_widgets_pro/widgets/media/QCustomImageViewer.py +300 -0
- custom_widgets_pro/widgets/media/QCustomMediaGrid.py +197 -0
- custom_widgets_pro/widgets/media/QCustomMediaTimeline.py +607 -0
- custom_widgets_pro/widgets/media/QCustomVideoPlayer.py +326 -0
- custom_widgets_pro/widgets/media/__init__.py +1 -0
- qt_pyqt_pyside_custom_widgets_pro-1.1.0.dist-info/METADATA +112 -0
- qt_pyqt_pyside_custom_widgets_pro-1.1.0.dist-info/RECORD +45 -0
- qt_pyqt_pyside_custom_widgets_pro-1.1.0.dist-info/WHEEL +5 -0
- qt_pyqt_pyside_custom_widgets_pro-1.1.0.dist-info/entry_points.txt +2 -0
- qt_pyqt_pyside_custom_widgets_pro-1.1.0.dist-info/licenses/LICENSE +91 -0
- qt_pyqt_pyside_custom_widgets_pro-1.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
########################################################################
|
|
2
|
+
## SPINN DESIGN CODE
|
|
3
|
+
# YOUTUBE: (SPINN TV) https://www.youtube.com/@SpinnTV
|
|
4
|
+
# WEBSITE: customwidgets.org
|
|
5
|
+
########################################################################
|
|
6
|
+
|
|
7
|
+
########################################################################
|
|
8
|
+
## QCustomRichTextEditor - a WYSIWYG rich-text editor.
|
|
9
|
+
##
|
|
10
|
+
## A formatting toolbar (bold / italic / underline / headings / lists /
|
|
11
|
+
## alignment / text colour / clear) over a QTextEdit. Tokenized. Exposes
|
|
12
|
+
## toHtml / setHtml / toPlainText / setPlainText and a `textChanged` signal.
|
|
13
|
+
########################################################################
|
|
14
|
+
from qtpy.QtCore import Qt, Signal
|
|
15
|
+
from qtpy.QtGui import (QFont, QTextCharFormat, QTextListFormat, QTextCursor,
|
|
16
|
+
QColor)
|
|
17
|
+
from qtpy.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QTextEdit,
|
|
18
|
+
QToolButton, QColorDialog)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class QCustomRichTextEditor(QWidget):
|
|
22
|
+
textChanged = Signal()
|
|
23
|
+
|
|
24
|
+
WIDGET_ICON = "components/icons/text_snippet.png"
|
|
25
|
+
WIDGET_TOOLTIP = "A WYSIWYG rich-text editor"
|
|
26
|
+
WIDGET_MODULE = "Custom_Widgets.QCustomRichTextEditor"
|
|
27
|
+
WIDGET_DOM_XML = """
|
|
28
|
+
<ui language='c++'>
|
|
29
|
+
<widget class='QCustomRichTextEditor' name='customRichTextEditor'>
|
|
30
|
+
<property name='geometry'><rect><x>0</x><y>0</y><width>420</width><height>300</height></rect></property>
|
|
31
|
+
</widget>
|
|
32
|
+
</ui>
|
|
33
|
+
"""
|
|
34
|
+
__catalog__ = {
|
|
35
|
+
"name": "QCustomRichTextEditor",
|
|
36
|
+
"props": {},
|
|
37
|
+
"signals": ["textChanged"],
|
|
38
|
+
"tokens_used": ["surface", "on-surface", "surface-muted", "outline",
|
|
39
|
+
"accent", "on-primary"],
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
# No Designer-editable properties: content is set in code via
|
|
43
|
+
# setHtml()/setPlainText(). Nothing to list in the Custom Properties dock.
|
|
44
|
+
DESIGNER_CUSTOM_PROPS = []
|
|
45
|
+
|
|
46
|
+
def __init__(self, parent=None):
|
|
47
|
+
super().__init__(parent)
|
|
48
|
+
self.setObjectName("QCustomRichTextEditor")
|
|
49
|
+
col = QVBoxLayout(self)
|
|
50
|
+
col.setContentsMargins(0, 0, 0, 0)
|
|
51
|
+
col.setSpacing(0)
|
|
52
|
+
|
|
53
|
+
self._toolbar = QWidget(self)
|
|
54
|
+
self._toolbar.setObjectName("rteToolbar")
|
|
55
|
+
bar = QHBoxLayout(self._toolbar)
|
|
56
|
+
bar.setContentsMargins(6, 6, 6, 6)
|
|
57
|
+
bar.setSpacing(2)
|
|
58
|
+
|
|
59
|
+
self._edit = QTextEdit(self)
|
|
60
|
+
self._edit.setObjectName("rteEditor")
|
|
61
|
+
self._edit.textChanged.connect(self.textChanged)
|
|
62
|
+
self._edit.currentCharFormatChanged.connect(self._syncButtons)
|
|
63
|
+
|
|
64
|
+
self._btns = {}
|
|
65
|
+
self._bold = self._toggle(bar, "B", self._applyBold, bold=True)
|
|
66
|
+
self._italic = self._toggle(bar, "I", self._applyItalic, italic=True)
|
|
67
|
+
self._underline = self._toggle(bar, "U", self._applyUnderline, underline=True)
|
|
68
|
+
self._sep(bar)
|
|
69
|
+
self._push(bar, "H1", lambda: self._heading(1))
|
|
70
|
+
self._push(bar, "H2", lambda: self._heading(2))
|
|
71
|
+
self._push(bar, "¶", lambda: self._heading(0))
|
|
72
|
+
self._sep(bar)
|
|
73
|
+
self._push(bar, "•", lambda: self._list(QTextListFormat.ListDisc))
|
|
74
|
+
self._push(bar, "1.", lambda: self._list(QTextListFormat.ListDecimal))
|
|
75
|
+
self._sep(bar)
|
|
76
|
+
self._push(bar, "⯇", lambda: self._edit.setAlignment(Qt.AlignLeft))
|
|
77
|
+
self._push(bar, "≡", lambda: self._edit.setAlignment(Qt.AlignCenter))
|
|
78
|
+
self._push(bar, "⯈", lambda: self._edit.setAlignment(Qt.AlignRight))
|
|
79
|
+
self._sep(bar)
|
|
80
|
+
self._push(bar, "A", self._textColor)
|
|
81
|
+
self._push(bar, "⌫", self._clearFormat)
|
|
82
|
+
bar.addStretch(1)
|
|
83
|
+
|
|
84
|
+
col.addWidget(self._toolbar)
|
|
85
|
+
col.addWidget(self._edit, 1)
|
|
86
|
+
|
|
87
|
+
# ------------------------------------------------------------------ #
|
|
88
|
+
## Toolbar builders
|
|
89
|
+
# ------------------------------------------------------------------ #
|
|
90
|
+
def _toggle(self, bar, text, slot, **font):
|
|
91
|
+
b = QToolButton(self._toolbar)
|
|
92
|
+
b.setObjectName("rteButton")
|
|
93
|
+
b.setText(text)
|
|
94
|
+
b.setCheckable(True)
|
|
95
|
+
b.setCursor(Qt.PointingHandCursor)
|
|
96
|
+
f = b.font()
|
|
97
|
+
f.setBold(font.get("bold", False))
|
|
98
|
+
f.setItalic(font.get("italic", False))
|
|
99
|
+
f.setUnderline(font.get("underline", False))
|
|
100
|
+
b.setFont(f)
|
|
101
|
+
b.clicked.connect(lambda checked: slot(checked))
|
|
102
|
+
bar.addWidget(b)
|
|
103
|
+
return b
|
|
104
|
+
|
|
105
|
+
def _push(self, bar, text, slot):
|
|
106
|
+
b = QToolButton(self._toolbar)
|
|
107
|
+
b.setObjectName("rteButton")
|
|
108
|
+
b.setText(text)
|
|
109
|
+
b.setCursor(Qt.PointingHandCursor)
|
|
110
|
+
b.clicked.connect(lambda: slot())
|
|
111
|
+
bar.addWidget(b)
|
|
112
|
+
return b
|
|
113
|
+
|
|
114
|
+
def _sep(self, bar):
|
|
115
|
+
s = QWidget(self._toolbar)
|
|
116
|
+
s.setObjectName("rteSep")
|
|
117
|
+
s.setFixedWidth(1)
|
|
118
|
+
bar.addWidget(s)
|
|
119
|
+
|
|
120
|
+
# ------------------------------------------------------------------ #
|
|
121
|
+
## Formatting
|
|
122
|
+
# ------------------------------------------------------------------ #
|
|
123
|
+
def _merge(self, fmt):
|
|
124
|
+
self._edit.mergeCurrentCharFormat(fmt)
|
|
125
|
+
|
|
126
|
+
def _applyBold(self, on):
|
|
127
|
+
fmt = QTextCharFormat()
|
|
128
|
+
fmt.setFontWeight(QFont.Bold if on else QFont.Normal)
|
|
129
|
+
self._merge(fmt)
|
|
130
|
+
|
|
131
|
+
def _applyItalic(self, on):
|
|
132
|
+
fmt = QTextCharFormat()
|
|
133
|
+
fmt.setFontItalic(on)
|
|
134
|
+
self._merge(fmt)
|
|
135
|
+
|
|
136
|
+
def _applyUnderline(self, on):
|
|
137
|
+
fmt = QTextCharFormat()
|
|
138
|
+
fmt.setFontUnderline(on)
|
|
139
|
+
self._merge(fmt)
|
|
140
|
+
|
|
141
|
+
def _heading(self, level):
|
|
142
|
+
sizes = {0: 12, 1: 22, 2: 17}
|
|
143
|
+
cursor = self._edit.textCursor()
|
|
144
|
+
cursor.select(QTextCursor.BlockUnderCursor)
|
|
145
|
+
fmt = QTextCharFormat()
|
|
146
|
+
fmt.setFontPointSize(sizes.get(level, 12))
|
|
147
|
+
fmt.setFontWeight(QFont.Bold if level > 0 else QFont.Normal)
|
|
148
|
+
cursor.mergeCharFormat(fmt)
|
|
149
|
+
self._edit.mergeCurrentCharFormat(fmt)
|
|
150
|
+
|
|
151
|
+
def _list(self, style):
|
|
152
|
+
cursor = self._edit.textCursor()
|
|
153
|
+
cursor.createList(QTextListFormat(style) if not isinstance(style, QTextListFormat)
|
|
154
|
+
else style)
|
|
155
|
+
|
|
156
|
+
def _textColor(self):
|
|
157
|
+
col = QColorDialog.getColor(self._edit.textColor(), self, "Text colour")
|
|
158
|
+
if col.isValid():
|
|
159
|
+
fmt = QTextCharFormat()
|
|
160
|
+
fmt.setForeground(col)
|
|
161
|
+
self._merge(fmt)
|
|
162
|
+
|
|
163
|
+
def _clearFormat(self):
|
|
164
|
+
cursor = self._edit.textCursor()
|
|
165
|
+
cursor.setCharFormat(QTextCharFormat())
|
|
166
|
+
self._edit.setCurrentCharFormat(QTextCharFormat())
|
|
167
|
+
|
|
168
|
+
def _syncButtons(self, fmt):
|
|
169
|
+
self._bold.setChecked(fmt.fontWeight() >= QFont.Bold)
|
|
170
|
+
self._italic.setChecked(fmt.fontItalic())
|
|
171
|
+
self._underline.setChecked(fmt.fontUnderline())
|
|
172
|
+
|
|
173
|
+
# ------------------------------------------------------------------ #
|
|
174
|
+
## Content API
|
|
175
|
+
# ------------------------------------------------------------------ #
|
|
176
|
+
def editor(self):
|
|
177
|
+
return self._edit
|
|
178
|
+
|
|
179
|
+
def toHtml(self):
|
|
180
|
+
return self._edit.toHtml()
|
|
181
|
+
|
|
182
|
+
def setHtml(self, html):
|
|
183
|
+
self._edit.setHtml(html)
|
|
184
|
+
|
|
185
|
+
def toPlainText(self):
|
|
186
|
+
return self._edit.toPlainText()
|
|
187
|
+
|
|
188
|
+
def setPlainText(self, text):
|
|
189
|
+
self._edit.setPlainText(text)
|