Este proyecto no recibe actualizaciones sustanciales y tendré tiempo limitado para ello en el futuro. Con la última versión, el proyecto se convirtió con bastante precisión en lo que quiero que sea: un editor y un marco fácil y flexible para explorar casos de uso de secuencias de comandos visuales basadas en flujo en Python. Si tiene preguntas o más ideas, no dude en abrir incidencias o bifurcar el proyecto y probarlo usted mismo.
Ryven es un editor de nodos experimental escrito en Python. Implementa una interfaz visual basada en Qt para secuencias de comandos visuales basadas en flujo en Python. Proporciona un potente sistema para desarrollar nodos que ejecuten cualquier código Python y un editor para crear gráficos utilizando esos nodos. Ryven presenta un montón de opciones de configuración y un modo sin cabeza para ejecutar gráficos sin ninguna GUI. Algunos repositorios de GitHub relevantes:
La biblioteca ryvencore-qt
agrega clases de GUI basadas en Qt para ryvencore ( ./ryvencore-qt/
), y el editor Ryven las reúne en una aplicación multiplataforma con todas las funciones ( ./ryven-editor/
).
Una vez que tenga Python y pip instalados, Ryven estará disponible en PyPI a través de
pip install ryven
También hay un paquete conda-forge ( conda install -c conda-forge ryven
).
Ryven se puede iniciar desde la línea de comando escribiendo ryven
. Si instaló Ryven en un entorno virtual Python (o un entorno conda), primero debe activar el entorno.
El propio Ryven solo viene con algunos pequeños nodos de ejemplo. Debe utilizar Ryven para desarrollar nodos o utilizar un paquete de nodos de terceros para su caso de uso, si existe uno. Los nodos de ejemplo son, de hecho, sólo ejemplos y no son estables de ninguna manera, por lo que no debes depender de ellos.
Cuando esté instalado, ryven creará un directorio ~/.ryven/
en su inicio de usuario con la siguiente estructura:
~/.ryven
├── nodes
│ ├── your_nodes_pkg_1
│ ├── nodes.py
│ └── gui.py
│ └── ...
├── saves
│ ├── your_project_1.json
│ └── ...
└── ryven.cfg
El archivo ryven.cfg
contiene configuraciones globales para Ryven.
Ryven se puede configurar de cuatro maneras:
ryven --nodes your_nodes_pkg_1 --no-animations
~/.ryven/ryven.cfg
: nodes = your_nodes_pkg_1 no_animations = True
import ryven ryven . run_ryven ( nodes = [ 'your_nodes_pkg_1' ], no_animations = True )
Escriba ryven --help
para obtener una lista de opciones disponibles.
Para implementar un proyecto Ryven sin cabeza (sin ninguna GUI), utilice el comando ryven-console
.
> ryven-console /home/leon/.ryven/saves/basics.json
Welcome to the Ryven Console ! Your project has been loaded.
You can access the ryvencore session by typing ` session ` .
For more information, visit https://leon-thomm.github.io/ryvencore/
>>> f = session.flows[0]
>>> ctr_var_result_node = f.nodes[2]
>>> ctr_set_var_node = f.nodes[8]
>>> ctr_var_result_node.val
3738
>>> ctr_set_var_node.update(0)
>>> ctr_var_result_node.val
3739
ryven
desde la línea de comandoFile -> Import Example Nodes
y seleccione <installation_dir>/example_nodes/std/nodes.py
val
a la escena+
result
ctrl + scroll
Un paquete de nodos Ryven es simplemente un paquete típico de Python que contiene al menos un archivo nodes.py
y llama a la API del nodo Ryven para exponer las definiciones de los nodos.
Navegue a ~/.ryven/nodes/
y cree un subdirectorio de la siguiente estructura
~/.ryven/nodes
└── your_nodes_pkg_1
├── __init__.py
├── nodes.py
└── gui.py
con los siguientes contenidos:
nodes.py
:
from ryven . node_env import *
# your node definitions go here
export_nodes ([
# list your node classes here
])
@ on_gui_load
def load_gui ():
# import gui sources here only
from . import gui
y gui.py
:
from ryven . gui_env import *
from . import nodes
# your node gui definitions go here
Ahora puede comenzar a definir sus propios nodos. Definamos dos nodos básicos. Uno que genera números aleatorios...
from random import random
class RandNode ( Node ):
"""Generates scaled random float values"""
title = 'Rand'
tags = [ 'random' , 'numbers' ]
init_inputs = [ NodeInputType ()]
init_outputs = [ NodeOutputType ()]
def update_event ( self , inp = - 1 ):
self . set_output_val ( 0 ,
Data ( random () * self . input ( 0 ). payload )
)
...y otro que los imprime
class PrintNode ( Node ):
title = 'Print'
init_inputs = [ NodeInputType ()]
def update_event ( self , inp = - 1 ):
print ( self . input ( 0 ))
y exponerlos a Ryven
export_nodes ([
RandNode ,
PrintNode ,
])
¡Eso es todo! Puede importar su paquete de nodos en Ryven ( File -> Import Nodes
), colocar los nodos en el gráfico y conectarlos. Agregue un nodo val
y conéctelo al nodo Rand
para alimentar su entrada con datos. Si escribe un número en el widget del nodo val
y presiona Enter, enviará el número al nodo Rand
, que enviará un número aleatorio escalado al nodo Print
, que lo imprimirá en la salida estándar.
Tenga en cuenta que la salida estándar es, de forma predeterminada, la consola del editor, a la que puede acceder en la parte inferior de la ventana del editor (arrastre el controlador azul hacia arriba para hacerlo visible).
Ahora puedes darle vida a tus nodos con alguna GUI. Ryven se ejecuta en Qt, usando PySide2 o PySide6 (a través de la biblioteca qtpy). Puede configurar la GUI de sus nodos en un archivo separado y agregar widgets Qt personalizados a sus nodos. Asegúrese de separar siempre claramente la lógica del nodo de los componentes de la GUI. Una de las características centrales de Ryven es ejecutar proyectos sin cabeza (en ryvencore) sin dependencias de GUI. Para que esto funcione, sus archivos nodes.py
nunca deberían depender directamente de Qt. En su lugar, puede adjuntar una GUI personalizada a sus nodos desde los archivos GUI como se muestra a continuación.
Démosles un poco de color y agreguemos un control deslizante al nodo Rand
, en gui.py
:
from qtpy . QtWidgets import QSlider
from qtpy . QtCore import Qt
from ryven . gui_env import *
from . import nodes
class RandSliderWidget ( NodeInputWidget , QSlider ):
"""a standard Qt slider widget, which updates the node
input it is attached to, every time the slider value changes"""
def __init__ ( self , params ):
NodeInputWidget . __init__ ( self , params )
QSlider . __init__ ( self )
self . setOrientation ( Qt . Horizontal )
self . setMinimumWidth ( 100 )
self . setMinimum ( 0 )
self . setMaximum ( 100 )
self . setValue ( 50 )
self . valueChanged . connect ( self . value_changed )
def value_changed ( self , val ):
# updates the node input this widget is attached to
self . update_node_input ( Data ( val ))
def get_state ( self ) -> dict :
# return the state of the widget
return { 'value' : self . value ()}
def set_state ( self , state : dict ):
# set the state of the widget
self . setValue ( state [ 'value' ])
@ node_gui ( nodes . RandNode )
class RandNodeGui ( NodeGUI ):
color = '#fcba03'
# register the input widget class
input_widget_classes = { 'slider' : RandSliderWidget }
# attach the slider widget to the first node input
# display it _below_ the input pin
init_input_widgets = {
0 : { 'name' : 'slider' , 'pos' : 'below' }
}
¡y esto es todo! Ryven ahora registrará RandNodeGui
como "clase GUI" de la clase RandNode
, que sirve como contenedor para todas las cosas de la interfaz de usuario. Puede agregar widgets primarios ("principales") personalizados a sus nodos, widgets de entrada y personalizar aún más el aspecto de los nodos.
El valor proporcionado por un widget de entrada (por ejemplo, self.update_node_input(val)
arriba) se devolverá en el nodo, al llamar input()
(por ejemplo, self.input(0)
en RandNode
), pero solo cuando la entrada correspondiente no sea conectado . De lo contrario, se devolverá el valor de la salida conectada.
Encuentre más recursos en la página wiki de GitHub en este repositorio.
A menos que indique explícitamente lo contrario, cualquier contribución enviada intencionalmente para su inclusión en el trabajo tendrá la licencia mencionada anteriormente, sin términos ni condiciones adicionales.
Las contribuciones son muy apreciadas. Este proyecto no existe sin la comunidad de código abierto. Quiero agradecer especialmente a las personas que figuran en el archivo CREDITS.md
.