Port Overview
Creating Custom Shapes
(Implemented on
v0.1.1
)To have custom port shapes the NodeGraphQt.BaseNode.add_input()
and
NodeGraphQt.BaseNode.add_output()
functions now have a painter_func
argument where you specify you custom port painter function.
Example Triangle Port
Here’s an example function for drawing a triangle port.
1def draw_triangle_port(painter, rect, info):
2 """
3 Custom paint function for drawing a Triangle shaped port.
4
5 Args:
6 painter (QtGui.QPainter): painter object.
7 rect (QtCore.QRectF): port rect used to describe parameters needed to draw.
8 info (dict): information describing the ports current state.
9 {
10 'port_type': 'in',
11 'color': (0, 0, 0),
12 'border_color': (255, 255, 255),
13 'multi_connection': False,
14 'connected': False,
15 'hovered': False,
16 }
17 """
18 painter.save()
19
20 # create triangle polygon.
21 size = int(rect.height() / 2)
22 triangle = QtGui.QPolygonF()
23 triangle.append(QtCore.QPointF(-size, size))
24 triangle.append(QtCore.QPointF(0.0, -size))
25 triangle.append(QtCore.QPointF(size, size))
26
27 # map polygon to port position.
28 transform = QtGui.QTransform()
29 transform.translate(rect.center().x(), rect.center().y())
30 port_poly = transform.map(triangle)
31
32 # mouse over port color.
33 if info['hovered']:
34 color = QtGui.QColor(14, 45, 59)
35 border_color = QtGui.QColor(136, 255, 35)
36 # port connected color.
37 elif info['connected']:
38 color = QtGui.QColor(195, 60, 60)
39 border_color = QtGui.QColor(200, 130, 70)
40 # default port color
41 else:
42 color = QtGui.QColor(*info['color'])
43 border_color = QtGui.QColor(*info['border_color'])
44
45 pen = QtGui.QPen(border_color, 1.8)
46 pen.setJoinStyle(QtCore.Qt.MiterJoin)
47
48 painter.setPen(pen)
49 painter.setBrush(color)
50 painter.drawPolygon(port_poly)
51
52 painter.restore()
The draw_triangle_port
painter function can then be passed to the painter_func
arg.
1from NodeGraphQt import BaseNode
2
3class MyListNode(BaseNode):
4
5 def __init__(self):
6 super(MyListNode, self).__init__()
7 # create a input port with custom painter function.
8 self.add_input('triangle', painter_func=draw_triangle_port)
Example Square Port
And here’s another example function for drawing a Square port.
1def draw_square_port(painter, rect, info):
2 """
3 Custom paint function for drawing a Square shaped port.
4
5 Args:
6 painter (QtGui.QPainter): painter object.
7 rect (QtCore.QRectF): port rect used to describe parameters needed to draw.
8 info (dict): information describing the ports current state.
9 {
10 'port_type': 'in',
11 'color': (0, 0, 0),
12 'border_color': (255, 255, 255),
13 'multi_connection': False,
14 'connected': False,
15 'hovered': False,
16 }
17 """
18 painter.save()
19
20 # mouse over port color.
21 if info['hovered']:
22 color = QtGui.QColor(14, 45, 59)
23 border_color = QtGui.QColor(136, 255, 35, 255)
24 # port connected color.
25 elif info['connected']:
26 color = QtGui.QColor(195, 60, 60)
27 border_color = QtGui.QColor(200, 130, 70)
28 # default port color
29 else:
30 color = QtGui.QColor(*info['color'])
31 border_color = QtGui.QColor(*info['border_color'])
32
33 pen = QtGui.QPen(border_color, 1.8)
34 pen.setJoinStyle(QtCore.Qt.MiterJoin)
35
36 painter.setPen(pen)
37 painter.setBrush(color)
38 painter.drawRect(rect)
39
40 painter.restore()
Connection Constrains
From version v0.6.0
port object can now have pipe connection constraints the functions implemented are:
this can also be set on the BaseNode
level as well with:
Here’s an example snippet to add pipe connection constraints to a port.
1from NodeGraphQt import BaseNode
2from NodeGraphQt.constants import PortTypeEnum
3
4
5class BasicNodeA(BaseNode):
6
7 # unique node identifier.
8 __identifier__ = 'io.github.jchanvfx'
9
10 # initial default node name.
11 NODE_NAME = 'node A'
12
13 def __init__(self):
14 super(BasicNode, self).__init__()
15
16 # create node output ports.
17 self.add_output('output 1')
18 self.add_output('output 2')
19
20
21class BasicNodeB(BaseNode):
22
23 # unique node identifier.
24 __identifier__ = 'io.github.jchanvfx'
25
26 # initial default node name.
27 NODE_NAME = 'node B'
28
29 def __init__(self):
30 super(BasicNode, self).__init__()
31
32 # create node inputs.
33
34 # port "in A" will only accept pipe connections from port "output 1"
35 # under the node "BasicNodeA".
36 in_port_a = self.add_input('in A')
37 in_port_a.add_accept_port_type(
38 port_name='output 1',
39 port_type=PortTypeEnum.OUT.value,
40 node_type='io.github.jchanvfx.BasicNodeA'
41 )
42
43 # port "in A" will reject pipe connections from port "output 1"
44 # under the node "BasicNodeA".
45 in_port_b = self.add_input('in B')
46 in_port_b.add_reject_port_type(
47 port_name='output 1',
48 port_type=PortTypeEnum.OUT.value,
49 node_type='io.github.jchanvfx.BasicNodeA'
50 )