cycles.py 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. #!/usr/bin/python3
  2. """
  3. This example shall explain how it is possible to do use cyclic graphs in
  4. libgtkflow. This example features a counter-node that will trigger itself
  5. to count up to a specific numeric value (self.target). To achieve the desired
  6. effect, please connect the counted-source with the clock-sink, so the node
  7. will propagate the desired signal to itself.
  8. """
  9. import gi
  10. gi.require_version('Gtk', '3.0')
  11. gi.require_version('GFlow', '0.10')
  12. gi.require_version('GtkFlow', '0.10')
  13. from gi.repository import GLib
  14. from gi.repository import Gtk
  15. from gi.repository import GFlow
  16. from gi.repository import GtkFlow
  17. import sys
  18. class ExampleNode(GFlow.SimpleNode):
  19. def __new__(cls, *args, **kwargs):
  20. x = GFlow.SimpleNode.new()
  21. x.__class__ = cls
  22. return x
  23. class StarterNode(ExampleNode):
  24. def __init__(self):
  25. self.emitter = GFlow.SimpleSource.with_type(int)
  26. self.emitter.set_name("emitter")
  27. self.add_source(self.emitter)
  28. self.button = Gtk.Button.new()
  29. self.button.set_label("Start!")
  30. self.button.connect("clicked", self.do_send_start)
  31. self.set_name("Counter")
  32. def do_send_start(self, dock, val=None):
  33. self.emitter.set_value(1)
  34. class CountNode(ExampleNode):
  35. def __init__(self):
  36. self.counter = 0
  37. self.target = 10
  38. self.enabled = False
  39. self.enable = GFlow.SimpleSink.with_type(int)
  40. self.clock = GFlow.SimpleSink.with_type(int)
  41. self.enable.set_name("enable")
  42. self.clock.set_name("clock")
  43. self.add_sink(self.enable)
  44. self.add_sink(self.clock)
  45. self.result = GFlow.SimpleSource.with_type(int)
  46. self.counted = GFlow.SimpleSource.with_type(int)
  47. self.result.set_value(0)
  48. self.counted.set_value(0)
  49. self.result.set_name("result")
  50. self.counted.set_name("counted")
  51. self.add_source(self.result)
  52. self.add_source(self.counted)
  53. self.enable.connect("changed", self.do_calculations, "enable")
  54. self.clock.connect("changed", self.do_calculations, "clock")
  55. self.set_name("Counter")
  56. def do_calculations(self, dock, val=None, flow_id=None, affiliation=None):
  57. if affiliation == "enable":
  58. self.enabled = val == 1
  59. elif affiliation == "clock" and self.enabled:
  60. if self.counter < self.target:
  61. self.counter += 1
  62. self.counted.set_value(self.counter)
  63. self.result.set_value(self.counter)
  64. class PrintNode(ExampleNode):
  65. def __init__(self):
  66. self.number = GFlow.SimpleSink.with_type(int)
  67. self.number.set_name("input")
  68. self.number.connect("changed", self.do_printing)
  69. self.add_sink(self.number)
  70. self.childlabel = Gtk.Label()
  71. self.set_name("Output")
  72. def do_printing(self, dock, val=None, flow_id=None):
  73. if val is not None:
  74. self.childlabel.set_text(str(val))
  75. else:
  76. self.childlabel.set_text("")
  77. class CountDemo(object):
  78. def __init__(self):
  79. w = Gtk.Window.new(Gtk.WindowType.TOPLEVEL)
  80. self.nv = GtkFlow.NodeView.new()
  81. # This deactivates nodeview's self-check for recursions
  82. self.nv.set_allow_recursion(True)
  83. self.nv.set_placeholder("Please click the buttons above to spawn nodes.")
  84. hbox = Gtk.Box.new(Gtk.Orientation.HORIZONTAL, 0)
  85. create_starternode_button = Gtk.Button.new_with_label("Create StarterNode")
  86. create_starternode_button.connect("clicked", self.do_create_starternode)
  87. hbox.add(create_starternode_button)
  88. create_countnode_button = Gtk.Button.new_with_label("Create CountNode")
  89. create_countnode_button.connect("clicked", self.do_create_countnode)
  90. hbox.add(create_countnode_button)
  91. create_printnode_button = Gtk.Button.new_with_label("Create PrintNode")
  92. create_printnode_button.connect("clicked", self.do_create_printnode)
  93. hbox.add(create_printnode_button)
  94. vbox = Gtk.Box.new(Gtk.Orientation.VERTICAL, 0)
  95. vbox.pack_start(hbox, False, False, 0)
  96. vbox.pack_start(self.nv, True, True, 0)
  97. w.add(vbox)
  98. w.add(self.nv)
  99. w.show_all()
  100. w.connect("destroy", self.do_quit)
  101. Gtk.main()
  102. def do_create_starternode(self, widget=None, data=None):
  103. n = StarterNode()
  104. self.nv.add_with_child(n, n.button)
  105. def do_create_countnode(self, widget=None, data=None):
  106. n = CountNode()
  107. self.nv.add_node(n)
  108. def do_create_printnode(self, widget=None, data=None):
  109. n = PrintNode()
  110. self.nv.add_with_child(n, n.childlabel)
  111. def do_quit(self, widget=None, data=None):
  112. Gtk.main_quit()
  113. sys.exit(0)
  114. if __name__ == "__main__":
  115. CountDemo()