nodeeditor-qtpy 0.8.1__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.
- nodeeditor/__init__.py +93 -0
- nodeeditor/node_colors_config.py +343 -0
- nodeeditor/node_content_widget.py +129 -0
- nodeeditor/node_decorators.py +65 -0
- nodeeditor/node_edge.py +518 -0
- nodeeditor/node_edge_dragging.py +185 -0
- nodeeditor/node_edge_intersect.py +219 -0
- nodeeditor/node_edge_rerouting.py +216 -0
- nodeeditor/node_edge_snapping.py +95 -0
- nodeeditor/node_edge_validators.py +82 -0
- nodeeditor/node_editor_widget.py +257 -0
- nodeeditor/node_editor_window.py +448 -0
- nodeeditor/node_graph.py +583 -0
- nodeeditor/node_graphics_cutline.py +57 -0
- nodeeditor/node_graphics_edge.py +375 -0
- nodeeditor/node_graphics_edge_path.py +226 -0
- nodeeditor/node_graphics_node.py +693 -0
- nodeeditor/node_graphics_scene.py +369 -0
- nodeeditor/node_graphics_socket.py +262 -0
- nodeeditor/node_graphics_view.py +907 -0
- nodeeditor/node_group.py +1286 -0
- nodeeditor/node_group_node.py +5 -0
- nodeeditor/node_icon_content_widget.py +176 -0
- nodeeditor/node_icon_graphics_node.py +524 -0
- nodeeditor/node_multi_input_node.py +450 -0
- nodeeditor/node_node.py +848 -0
- nodeeditor/node_scene.py +1106 -0
- nodeeditor/node_scene_clipboard.py +314 -0
- nodeeditor/node_scene_history.py +556 -0
- nodeeditor/node_serializable.py +43 -0
- nodeeditor/node_socket.py +445 -0
- nodeeditor/node_socket_shapes.py +261 -0
- nodeeditor/py.typed +0 -0
- nodeeditor/qss/nodestyle.qss +3 -0
- nodeeditor/utils.py +108 -0
- nodeeditor/utils_no_qt.py +21 -0
- nodeeditor_qtpy-0.8.1.dist-info/METADATA +165 -0
- nodeeditor_qtpy-0.8.1.dist-info/RECORD +40 -0
- nodeeditor_qtpy-0.8.1.dist-info/WHEEL +4 -0
- nodeeditor_qtpy-0.8.1.dist-info/licenses/LICENCE +23 -0
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""A module containing the base class for the Node's content graphical representation. It also contains an example of
|
|
3
|
+
an overridden Text Widget, which can pass a notification to it's parent about being modified."""
|
|
4
|
+
from collections import OrderedDict
|
|
5
|
+
from nodeeditor.node_content_widget import QDMNodeContentWidget
|
|
6
|
+
from nodeeditor.node_serializable import Serializable
|
|
7
|
+
from qtpy.QtWidgets import QWidget, QLabel, QVBoxLayout, QTextEdit
|
|
8
|
+
from qtpy.QtGui import QPixmap, QImage, QFocusEvent
|
|
9
|
+
from qtpy.QtCore import Qt
|
|
10
|
+
|
|
11
|
+
from typing import TYPE_CHECKING, List, Optional, Tuple, Any, Callable
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
if TYPE_CHECKING:
|
|
15
|
+
from nodeeditor.node_graphics_view import QDMGraphicsView
|
|
16
|
+
from nodeeditor.node_socket import Socket
|
|
17
|
+
from nodeeditor.node_scene import Scene
|
|
18
|
+
from nodeeditor.node_node import Node
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class QDMNodeIconContentWidget(QWidget, Serializable):
|
|
22
|
+
"""Base class for representation of the Node's graphics content. This class also provides layout
|
|
23
|
+
for other widgets inside of a :py:class:`~nodeeditor.node_node.Node`"""
|
|
24
|
+
|
|
25
|
+
def __init__(self, node: 'Node', parent: Optional[QWidget] = None) -> None:
|
|
26
|
+
"""
|
|
27
|
+
:param node: reference to the :py:class:`~nodeeditor.node_node.Node`
|
|
28
|
+
:type node: :py:class:`~nodeeditor.node_node.Node`
|
|
29
|
+
:param parent: parent widget
|
|
30
|
+
:type parent: QWidget
|
|
31
|
+
|
|
32
|
+
:Instance Attributes:
|
|
33
|
+
- **node** - reference to the :class:`~nodeeditor.node_node.Node`
|
|
34
|
+
- **layout** - ``QLayout`` container
|
|
35
|
+
"""
|
|
36
|
+
self.node = node
|
|
37
|
+
super().__init__(parent)
|
|
38
|
+
self.icon: QPixmap
|
|
39
|
+
|
|
40
|
+
self.initUI()
|
|
41
|
+
|
|
42
|
+
def initUI(self, icon: QPixmap = None) -> None:
|
|
43
|
+
"""Sets up layouts and widgets to be rendered in :py:class:`~nodeeditor.node_graphics_node.QDMGraphicsNode` class.
|
|
44
|
+
"""
|
|
45
|
+
|
|
46
|
+
#: Kept on the widget because the icon pixmap *is* the node's whole
|
|
47
|
+
#: look: consumers that repaint the node cheaply at low zoom blit this
|
|
48
|
+
#: instead of rendering the widget.
|
|
49
|
+
self.icon = icon
|
|
50
|
+
|
|
51
|
+
self.v_layout = QVBoxLayout()
|
|
52
|
+
self.v_layout.setContentsMargins(0, 0, 0, 0)
|
|
53
|
+
self.setLayout(self.v_layout)
|
|
54
|
+
|
|
55
|
+
# Add icon in the center
|
|
56
|
+
self.icon_label = QLabel(self)
|
|
57
|
+
|
|
58
|
+
# image = QImage("icons/in.png")
|
|
59
|
+
# if not image.isNull():
|
|
60
|
+
print("icon: ", icon)
|
|
61
|
+
print(type(icon))
|
|
62
|
+
if icon:
|
|
63
|
+
pixmap = icon
|
|
64
|
+
self.icon_label.setPixmap(pixmap)
|
|
65
|
+
self.icon_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
|
66
|
+
self.v_layout.addWidget(self.icon_label)
|
|
67
|
+
|
|
68
|
+
# self.layout = QVBoxLayout()
|
|
69
|
+
# self.layout.setContentsMargins(0, 0, 0, 0)
|
|
70
|
+
# self.setLayout(self.layout)
|
|
71
|
+
|
|
72
|
+
# self.wdg_label = QLabel("Some Title")
|
|
73
|
+
# self.layout.addWidget(self.wdg_label)
|
|
74
|
+
# self.layout.addWidget(QDMTextEdit("foo"))
|
|
75
|
+
|
|
76
|
+
# Add icon in the center
|
|
77
|
+
# self.icon_label = QLabel(self)
|
|
78
|
+
# if hasattr(self.node, 'picon') and isinstance(self.node.picon, QImage):
|
|
79
|
+
# image = self.node.picon
|
|
80
|
+
# print(image.isNull())
|
|
81
|
+
# # image = QImage(self.node.picon)
|
|
82
|
+
# if not image.isNull():
|
|
83
|
+
# pixmap = QPixmap.fromImage(image)
|
|
84
|
+
# self.icon_label.setPixmap(pixmap)
|
|
85
|
+
# self.icon_label.setAlignment(Qt.AlignCenter)
|
|
86
|
+
# self.layout.addWidget(self.icon_label)
|
|
87
|
+
# else:
|
|
88
|
+
# print(f"Failed to load image from path: {self.node.picon}")
|
|
89
|
+
# else:
|
|
90
|
+
# print("Node does not have a valid 'picon' attribute or it is not a QImage")
|
|
91
|
+
|
|
92
|
+
# Assuming node has an icon_path attribute
|
|
93
|
+
# image = QImage(self.node.picon)
|
|
94
|
+
# image = self.node.picon
|
|
95
|
+
# pixmap = QPixmap.fromImage(image)
|
|
96
|
+
# self.icon_label.setPixmap(pixmap)
|
|
97
|
+
# self.icon_label.setAlignment(Qt.AlignCenter)
|
|
98
|
+
# self.layout.addWidget(self.icon_label)
|
|
99
|
+
|
|
100
|
+
def setEditingFlag(self, value: bool) -> None:
|
|
101
|
+
"""
|
|
102
|
+
.. note::
|
|
103
|
+
|
|
104
|
+
If you are handling keyPress events by default Qt Window's shortcuts and ``QActions``, you will not
|
|
105
|
+
need to use this method.
|
|
106
|
+
|
|
107
|
+
Helper function which sets editingFlag inside :py:class:`~nodeeditor.node_graphics_view.QDMGraphicsView` class.
|
|
108
|
+
|
|
109
|
+
This is a helper function to handle keys inside nodes with ``QLineEdits`` or ``QTextEdits`` (you can
|
|
110
|
+
use overridden :py:class:`QDMTextEdit` class) and with QGraphicsView class method ``keyPressEvent``.
|
|
111
|
+
|
|
112
|
+
:param value: new value for editing flag
|
|
113
|
+
"""
|
|
114
|
+
self.node.scene.getView().editingFlag = value
|
|
115
|
+
|
|
116
|
+
def serialize(self) -> OrderedDict:
|
|
117
|
+
"""Serialization method to serialize this class data into ``OrderedDict``.
|
|
118
|
+
|
|
119
|
+
:return: data serialized in ``OrderedDict``
|
|
120
|
+
:rtype: ``OrderedDict``
|
|
121
|
+
"""
|
|
122
|
+
return OrderedDict([
|
|
123
|
+
])
|
|
124
|
+
|
|
125
|
+
def deserialize(self, data: dict, hashmap: dict = {}, restore_id: bool = True) -> bool:
|
|
126
|
+
"""Deserialization method which takes data in python ``dict`` format.
|
|
127
|
+
|
|
128
|
+
The icon content holds no state of its own, so there is nothing to
|
|
129
|
+
restore and the call always succeeds.
|
|
130
|
+
|
|
131
|
+
:param data: Dictionary containing serialized data
|
|
132
|
+
:type data: ``dict``
|
|
133
|
+
:param hashmap: Helper dictionary containing references (by id == key) to existing objects
|
|
134
|
+
:type hashmap: ``dict``
|
|
135
|
+
:param restore_id: True if we are creating new objects. False is useful when loading existing
|
|
136
|
+
objects of which we want to keep the existing object's `id`.
|
|
137
|
+
:type restore_id: bool
|
|
138
|
+
:return: ``True`` if deserialization was successful, otherwise ``False``
|
|
139
|
+
:rtype: ``bool``
|
|
140
|
+
"""
|
|
141
|
+
return True
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
class QDMTextEdit(QTextEdit):
|
|
145
|
+
"""
|
|
146
|
+
.. note::
|
|
147
|
+
|
|
148
|
+
This class is an example of a ``QTextEdit`` modification that handles the `Delete` key event with an overridden
|
|
149
|
+
Qt's ``keyPressEvent`` (when not using ``QActions`` in menu or toolbar)
|
|
150
|
+
|
|
151
|
+
Overridden ``QTextEdit`` which sends a notification about being edited to its parent's container :py:class:`QDMNodeContentWidget`
|
|
152
|
+
"""
|
|
153
|
+
|
|
154
|
+
def focusInEvent(self, event: QFocusEvent | None) -> None:
|
|
155
|
+
"""Example of an overridden focusInEvent to mark the start of editing
|
|
156
|
+
|
|
157
|
+
:param event: Qt's focus event
|
|
158
|
+
:type event: QFocusEvent
|
|
159
|
+
"""
|
|
160
|
+
parent = self.parentWidget()
|
|
161
|
+
if isinstance(parent, QDMNodeContentWidget):
|
|
162
|
+
parent.setEditingFlag(True)
|
|
163
|
+
|
|
164
|
+
super().focusInEvent(event)
|
|
165
|
+
|
|
166
|
+
def focusOutEvent(self, event: QFocusEvent | None) -> None:
|
|
167
|
+
"""Example of an overridden focusOutEvent to mark the end of editing
|
|
168
|
+
|
|
169
|
+
:param event: Qt's focus event
|
|
170
|
+
:type event: QFocusEvent
|
|
171
|
+
"""
|
|
172
|
+
parent = self.parentWidget()
|
|
173
|
+
if isinstance(parent, QDMNodeContentWidget):
|
|
174
|
+
parent.setEditingFlag(False)
|
|
175
|
+
|
|
176
|
+
super().focusOutEvent(event)
|