jchanvfx / NodeGraphQt

Node graph framework that can be re-implemented into applications that supports PySide2
http://chantonic.com/NodeGraphQt/
MIT License
1.24k stars 251 forks source link

Update and values transmission #318

Closed Zelfior closed 1 year ago

Zelfior commented 1 year ago

Hi,

It is more a question than a bug. about how we can actually use it.

Can we access to data from nodes that are linked to the current node? For example if we want to make a sum or multiply node.

How are nodes updated, is the model_update function called everytime there is a change in a tree? does it propagate to the nodes present in the tree? To go back to the multiply example, it would let update the value if we change one of the summed values.

Thanks

jchanvfx commented 1 year ago

Hi @Zelfior

Currently NodeGraphQt is more of a UI framework that can be customized, any of the business logic you'll need to implement on top of it.

Here's a link to a basic setup for a node graph. https://jchanvfx.github.io/NodeGraphQt/api/examples/ex_overview.html#getting-started

The node graph also has a NodeGraph.property_changed signal. https://jchanvfx.github.io/NodeGraphQt/api/graph.html#NodeGraphQt.NodeGraph.property_changed

Here's a snippet to get values from a connected node:

 from Qt import QtWidgets

from NodeGraphQt import NodeGraph, BaseNode

class TestNode(BaseNode):

    __identifier__ = 'my.test'
    NODE_NAME = 'My Text Node'

    def __init__(self):
        super(TestNode, self).__init__()
        self.add_input('in')
        self.add_output('out')
        self.add_text_input('baz', text='hello')
        self.create_property('foo', 'bacon')
        self.create_property('bar', 'eggs')

if __name__ == '__main__':
    app = QtWidgets.QApplication([])

    graph = NodeGraph()
    graph.register_node(TestNode)
    graph.show()

    node_A = graph.create_node('my.test.TestNode')
    node_B = graph.create_node('my.test.TestNode')

    # connect the 2 nodes.
    node_B.set_input(0, node_A.output(1))

    # get the name of node_A from the connected input of node_B
    print(node_B.input(0).connected_ports()[0].node().name())

    # get the value of node_A "baz" property from the connected input of node_B
    print(node_B.input(0).connected_ports()[0].node().get_property('baz'))

    app.exec_()
Zelfior commented 1 year ago

@jchanvfx Thanks for your answer :D

I managed to make the value transmission and children updates when a value is changed now.

I would like to get to draw an image within a node, ideally put a matplotlib inside a node. It is possible to do with QWidgets through FigureCanvasQTAgg from matplotlib.backends.backend_qt5agg. Have you ever tried doing so within your framework? I tried a couple of things, a node is created at what seems to be the right size, but nothing is shown within the node. I am curious about how you would approach the problem and in which classes you would add the widgets definitions.

(You can find in my depo a gross copy of yours that i changed for debug purpose, i'm not planning to claim your code)

Thanks Zelfior

jchanvfx commented 1 year ago

Cool all good @Zelfior if you’re wanting to embed an image into a node you could do by setting an image on a QLabel widget and then adding that into the node.

Here’s an example on embedded a custom widget.

https://jchanvfx.github.io/NodeGraphQt/api/examples/ex_node.html#embedding-custom-widgets

Zelfior commented 1 year ago

Thanks for the link, i managed to make it work :)

Capture du 2023-04-07 09-52-44

jchanvfx commented 1 year ago

Nice!