1616from NodeGraphQt .base .port import Port
1717from NodeGraphQt .constants import (DRAG_DROP_ID ,
1818 PIPE_LAYOUT_CURVED ,
19- PIPE_LAYOUT_STRAIGHT )
19+ PIPE_LAYOUT_STRAIGHT ,
20+ PIPE_LAYOUT_ANGLE ,
21+ IN_PORT , OUT_PORT )
2022from NodeGraphQt .widgets .viewer import NodeViewer
2123
2224
2325class NodeGraph (QtCore .QObject ):
2426 """
25- base node graph controller.
27+ The ``NodeGraph`` class is the main controller for managing all nodes.
28+
29+ Inherited from: ``PySide2.QtCore.QObject``
30+
31+ .. image:: _images/graph.png
32+ :width: 60%
2633 """
2734
28- #: signal emits the node object when a node is created in the node graph.
35+ #:QtCore.Signal: emits the node object when a node is created in the node graph.
2936 node_created = QtCore .Signal (NodeObject )
30- #: signal emits a list of node ids from the deleted nodes.
37+ #:QtCore.Signal: emits a `` list[str]`` of node ids from the deleted nodes.
3138 nodes_deleted = QtCore .Signal (list )
32- #: signal emits the node object when selected in the node graph.
39+ #:QtCore.Signal: emits the node object when selected in the node graph.
3340 node_selected = QtCore .Signal (NodeObject )
34- #: signal triggered when a node is double clicked and emits the node.
41+ #:QtCore.Signal: triggered when a node is double clicked and emits the node.
3542 node_double_clicked = QtCore .Signal (NodeObject )
36- #: signal for when a node has been connected emits (source port, target port).
43+ #:QtCore.Signal: for when a node has been connected emits (``input port``, ``output port`` ).
3744 port_connected = QtCore .Signal (Port , Port )
38- #: signal for when a node has been disconnected emits (source port, target port).
45+ #:QtCore.Signal: for when a node has been disconnected emits (``input port``, ``output port`` ).
3946 port_disconnected = QtCore .Signal (Port , Port )
40- #: signal for when a node property has changed emits (node, property name, property value).
47+ #:QtCore.Signal: for when a node property has changed emits (`` node``, `` property name``, `` property value`` ).
4148 property_changed = QtCore .Signal (NodeObject , str , object )
42- #: signal for when drop data has been added to the graph.
49+ #:QtCore.Signal: for when drop data has been added to the graph.
4350 data_dropped = QtCore .Signal (QtCore .QMimeData , QtCore .QPoint )
4451
4552 def __init__ (self , parent = None ):
4653 super (NodeGraph , self ).__init__ (parent )
4754 self .setObjectName ('NodeGraphQt' )
55+ self ._widget = None
4856 self ._model = NodeGraphModel ()
49- self ._viewer = NodeViewer (parent )
57+ self ._viewer = NodeViewer ()
5058 self ._node_factory = NodeFactory ()
5159 self ._undo_stack = QtWidgets .QUndoStack (self )
5260
@@ -176,7 +184,7 @@ def _on_connection_changed(self, disconnected, connected):
176184 return
177185
178186 label = 'connect node(s)' if connected else 'disconnect node(s)'
179- ptypes = {'in' : 'inputs' , 'out' : 'outputs' }
187+ ptypes = {IN_PORT : 'inputs' , OUT_PORT : 'outputs' }
180188
181189 self ._undo_stack .beginMacro (label )
182190 for p1_view , p2_view in disconnected :
@@ -203,7 +211,7 @@ def _on_connection_sliced(self, ports):
203211 """
204212 if not ports :
205213 return
206- ptypes = {'in' : 'inputs' , 'out' : 'outputs' }
214+ ptypes = {IN_PORT : 'inputs' , OUT_PORT : 'outputs' }
207215 self ._undo_stack .beginMacro ('slice connections' )
208216 for p1_view , p2_view in ports :
209217 node1 = self ._model .nodes [p1_view .node .id ]
@@ -216,33 +224,56 @@ def _on_connection_sliced(self, ports):
216224 @property
217225 def model (self ):
218226 """
219- Returns the model used to store the node graph data.
227+ The model used for storing the node graph data.
220228
221229 Returns:
222230 NodeGraphQt.base.model.NodeGraphModel: node graph model.
223231 """
224232 return self ._model
225233
234+ @property
235+ def widget (self ):
236+ """
237+ The node graph widget for adding into a layout.
238+
239+ Returns:
240+ QtWidgets.QWidget: node graph widget.
241+ """
242+ if self ._widget is None :
243+ self ._widget = QtWidgets .QWidget ()
244+ layout = QtWidgets .QVBoxLayout (self ._widget )
245+ layout .setContentsMargins (0 , 0 , 0 , 0 )
246+ layout .addWidget (self ._viewer )
247+ return self ._widget
248+
226249 def show (self ):
227250 """
228- Show node graph viewer widget this is just a convenience
229- function to :meth:`NodeGraph.viewer ().show()`.
251+ Show node graph widget this is just a convenience
252+ function to :meth:`NodeGraph.widget ().show()`.
230253 """
231- self ._viewer .show ()
254+ self ._widget .show ()
232255
233256 def close (self ):
234257 """
235258 Close node graph NodeViewer widget this is just a convenience
236- function to :meth:`NodeGraph.viewer ().close()`.
259+ function to :meth:`NodeGraph.widget ().close()`.
237260 """
238- self ._viewer .close ()
261+ self ._widget .close ()
239262
240263 def viewer (self ):
241264 """
242- Return the node graph viewer widget.
265+ Returns the view interface used by the node graph.
266+
267+ Warnings:
268+ Methods in the `NodeViewer` are used internally
269+ by `NodeGraphQt` components.
270+
271+ See Also:
272+ :attr:`NodeGraph.widget` for adding the node graph into a
273+ QtWidgets.QLayout.
243274
244275 Returns:
245- NodeGraphQt.widgets.viewer.NodeViewer: viewer widget .
276+ NodeGraphQt.widgets.viewer.NodeViewer: viewer interface .
246277 """
247278 return self ._viewer
248279
@@ -315,7 +346,11 @@ def add_properties_bin(self, prop_bin):
315346
316347 def undo_stack (self ):
317348 """
318- Returns the undo stack used in the node graph
349+ Returns the undo stack used in the node graph.
350+
351+ See Also:
352+ :meth:`NodeGraph.begin_undo()`,
353+ :meth:`NodeGraph.end_undo()`
319354
320355 Returns:
321356 QtWidgets.QUndoStack: undo stack.
@@ -325,7 +360,15 @@ def undo_stack(self):
325360 def clear_undo_stack (self ):
326361 """
327362 Clears the undo stack.
328- (convenience function to :meth:`NodeGraph.undo_stack().clear`)
363+
364+ Note:
365+ Convenience function to
366+ :meth:`NodeGraph.undo_stack().clear()`
367+
368+ See Also:
369+ :meth:`NodeGraph.begin_undo()`,
370+ :meth:`NodeGraph.end_undo()`,
371+ :meth:`NodeGraph.undo_stack()`
329372 """
330373 self ._undo_stack .clear ()
331374
@@ -411,19 +454,26 @@ def set_acyclic(self, mode=False):
411454 self ._model .acyclic = mode
412455 self ._viewer .acyclic = mode
413456
414- def set_pipe_style (self , style = None ):
457+ def set_pipe_style (self , style = PIPE_LAYOUT_CURVED ):
415458 """
416- Set node graph pipes to be drawn straight or curved by default
417- all pipes are set curved. (default=0)
459+ Set node graph pipes to be drawn as straight, curved or angled.
460+
461+ Note:
462+ By default all pipes are set curved.
463+
464+ Pipe Layout Styles:
418465
419- ``NodeGraphQt.constants.PIPE_LAYOUT_CURVED`` = 0
420- ``NodeGraphQt.constants.PIPE_LAYOUT_STRAIGHT`` = 1
466+ * :attr:`NodeGraphQt.constants.PIPE_LAYOUT_CURVED`
467+ * :attr:`NodeGraphQt.constants.PIPE_LAYOUT_STRAIGHT`
468+ * :attr:`NodeGraphQt.constants.PIPE_LAYOUT_ANGLE`
421469
422470 Args:
423- style (int): pipe style.
471+ style (int): pipe layout style.
424472 """
425- pipe_default = max ([PIPE_LAYOUT_CURVED , PIPE_LAYOUT_STRAIGHT ])
426- style = PIPE_LAYOUT_STRAIGHT if style > pipe_default else style
473+ pipe_max = max ([PIPE_LAYOUT_CURVED ,
474+ PIPE_LAYOUT_STRAIGHT ,
475+ PIPE_LAYOUT_ANGLE ])
476+ style = style if 0 >= style >= pipe_max else PIPE_LAYOUT_CURVED
427477 self ._viewer .set_pipe_layout (style )
428478
429479 def fit_to_selection (self ):
@@ -480,7 +530,8 @@ def registered_nodes(self):
480530 """
481531 Return a list of all node types that have been registered.
482532
483- To register a node see :meth:`NodeGraph.register_node`
533+ See Also:
534+ To register a node :meth:`NodeGraph.register_node`
484535
485536 Returns:
486537 list[str]: list of node type identifiers.
@@ -502,7 +553,8 @@ def create_node(self, node_type, name=None, selected=True, color=None,
502553 """
503554 Create a new node in the node graph.
504555
505- (To list all node types see :meth:`NodeGraph.registered_nodes`)
556+ See Also:
557+ To list all node types :meth:`NodeGraph.registered_nodes`
506558
507559 Args:
508560 node_type (str): node instance type.
@@ -753,14 +805,16 @@ def _serialize(self, nodes):
753805 for pname , conn_data in inputs .items ():
754806 for conn_id , prt_names in conn_data .items ():
755807 for conn_prt in prt_names :
756- pipe = {'in' : [n_id , pname ], 'out' : [conn_id , conn_prt ]}
808+ pipe = {IN_PORT : [n_id , pname ],
809+ OUT_PORT : [conn_id , conn_prt ]}
757810 if pipe not in serial_data ['connections' ]:
758811 serial_data ['connections' ].append (pipe )
759812
760813 for pname , conn_data in outputs .items ():
761814 for conn_id , prt_names in conn_data .items ():
762815 for conn_prt in prt_names :
763- pipe = {'out' : [n_id , pname ], 'in' : [conn_id , conn_prt ]}
816+ pipe = {OUT_PORT : [n_id , pname ],
817+ IN_PORT : [conn_id , conn_prt ]}
764818 if pipe not in serial_data ['connections' ]:
765819 serial_data ['connections' ].append (pipe )
766820
@@ -837,6 +891,17 @@ def serialize_session(self):
837891 """
838892 return self ._serialize (self .all_nodes ())
839893
894+ def deserialize_session (self , layout_data ):
895+ """
896+ Load node graph session from a dictionary object.
897+
898+ Args:
899+ layout_data (dict): dictionary object containing a node session.
900+ """
901+ self .clear_session ()
902+ self ._deserialize (layout_data )
903+ self ._undo_stack .clear ()
904+
840905 def save_session (self , file_path ):
841906 """
842907 Saves the current node graph session layout to a `JSON` formatted file.
@@ -940,7 +1005,8 @@ def disable_nodes(self, nodes, mode=None):
9401005 """
9411006 Set weather to Disable or Enable specified nodes.
9421007
943- see: :meth:`NodeObject.set_disabled`
1008+ See Also:
1009+ :meth:`NodeObject.set_disabled`
9441010
9451011 Args:
9461012 nodes (list[NodeGraphQt.BaseNode]): list of node instances.
@@ -964,7 +1030,9 @@ def question_dialog(self, text, title='Node Graph'):
9641030 Prompts a question open dialog with "Yes" and "No" buttons in
9651031 the node graph.
9661032
967- (convenience function to :meth:`NodeGraph.viewer().question_dialog`)
1033+ Note:
1034+ Convenience function to
1035+ :meth:`NodeGraphQt.NodeGraph.viewer().question_dialog`
9681036
9691037 Args:
9701038 text (str): question text.
@@ -979,7 +1047,9 @@ def message_dialog(self, text, title='Node Graph'):
9791047 """
9801048 Prompts a file open dialog in the node graph.
9811049
982- (convenience function to :meth:`NodeGraph.viewer().message_dialog`)
1050+ Note:
1051+ Convenience function to
1052+ :meth:`NodeGraphQt.NodeGraph.viewer().message_dialog`
9831053
9841054 Args:
9851055 text (str): message text.
@@ -991,7 +1061,9 @@ def load_dialog(self, current_dir=None, ext=None):
9911061 """
9921062 Prompts a file open dialog in the node graph.
9931063
994- (convenience function to :meth:`NodeGraph.viewer().load_dialog`)
1064+ Note:
1065+ Convenience function to
1066+ :meth:`NodeGraphQt.NodeGraph.viewer().load_dialog`
9951067
9961068 Args:
9971069 current_dir (str): path to a directory.
@@ -1006,7 +1078,9 @@ def save_dialog(self, current_dir=None, ext=None):
10061078 """
10071079 Prompts a file save dialog in the node graph.
10081080
1009- (convenience function to :meth:`NodeGraph.viewer().save_dialog`)
1081+ Note:
1082+ Convenience function to
1083+ :meth:`NodeGraphQt.NodeGraph.viewer().save_dialog`
10101084
10111085 Args:
10121086 current_dir (str): path to a directory.
0 commit comments