Ce projet ne reçoit pas de mises à jour substantielles et je disposerai de peu de temps pour le consacrer à l'avenir. Avec la dernière version, le projet est devenu assez précisément ce que je souhaitais : un éditeur et un framework simples et flexibles pour explorer les cas d'utilisation de scripts visuels basés sur des flux en Python. Si vous avez des questions ou d'autres idées, n'hésitez pas à ouvrir des problèmes ou à lancer le projet et à l'essayer vous-même.
Ryven est un éditeur de nœuds expérimental écrit en Python. Il implémente une interface visuelle basée sur Qt pour les scripts visuels basés sur les flux en Python. Il fournit un système puissant pour développer des nœuds exécutant n'importe quel code Python, ainsi qu'un éditeur pour créer des graphiques à l'aide de ces nœuds. Ryven propose de nombreuses options de configuration et un mode sans tête pour exécuter des graphiques sans aucune interface graphique. Quelques dépôts GitHub pertinents :
La bibliothèque ryvencore-qt
ajoute des classes d'interface graphique basées sur Qt pour ryvencore ( ./ryvencore-qt/
), et l'éditeur Ryven les assemble dans une application multiplateforme complète ( ./ryven-editor/
).
Une fois Python et pip installés, Ryven est disponible sur PyPI via
pip install ryven
Il existe également un package conda-forge ( conda install -c conda-forge ryven
).
Ryven peut être lancé depuis la ligne de commande en tapant ryven
. Si vous avez installé Ryven dans un environnement virtuel Python (ou un environnement conda), l'environnement doit d'abord être activé.
Ryven lui-même n'est livré qu'avec quelques petits exemples de nœuds. Vous devez utiliser Ryven soit pour développer des nœuds, soit utiliser un package de nœuds tiers pour votre cas d'utilisation, le cas échéant. Les exemples de nœuds ne sont - en effet - que des exemples, et ne sont en aucun cas stables, vous ne devez donc pas en dépendre.
Une fois installé, ryven créera un répertoire ~/.ryven/
dans votre répertoire utilisateur avec la structure suivante :
~/.ryven
├── nodes
│ ├── your_nodes_pkg_1
│ ├── nodes.py
│ └── gui.py
│ └── ...
├── saves
│ ├── your_project_1.json
│ └── ...
└── ryven.cfg
Le fichier ryven.cfg
contient les configurations globales pour Ryven.
Ryven peut être configuré de quatre manières :
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 )
Tapez ryven --help
pour une liste des options disponibles.
Pour déployer un projet Ryven sans tête (sans aucune interface graphique), utilisez la commande 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
à partir de la ligne de commandeFile -> Import Example Nodes
et sélectionnez <installation_dir>/example_nodes/std/nodes.py
val
dans la scène+
result
ctrl + scroll
Un package de nœuds Ryven est simplement un package Python typique qui contient au moins un fichier nodes.py
et appelle l'API de nœud Ryven pour exposer les définitions de nœuds.
Accédez à ~/.ryven/nodes/
et créez un sous-répertoire de la structure suivante
~/.ryven/nodes
└── your_nodes_pkg_1
├── __init__.py
├── nodes.py
└── gui.py
avec le contenu suivant :
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
et gui.py
:
from ryven . gui_env import *
from . import nodes
# your node gui definitions go here
Vous pouvez maintenant commencer à définir vos propres nœuds. Définissons deux nœuds de base. Celui qui génère des nombres aléatoires...
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 )
)
...et un autre qui les imprime
class PrintNode ( Node ):
title = 'Print'
init_inputs = [ NodeInputType ()]
def update_event ( self , inp = - 1 ):
print ( self . input ( 0 ))
et exposez-les à Ryven
export_nodes ([
RandNode ,
PrintNode ,
])
C'est ça! Vous pouvez importer votre package de nœuds dans Ryven ( File -> Import Nodes
), placer les nœuds dans le graphique et les connecter. Ajoutez un nœud val
et connectez-le au nœud Rand
, pour alimenter son entrée en données. Si vous tapez un nombre dans le widget du nœud val
et appuyez sur Entrée, il enverra le numéro au nœud Rand
, qui enverra un nombre aléatoire mis à l'échelle au nœud Print
, qui l'imprimera sur la sortie standard.
Notez que la sortie standard est par défaut la console de l'éditeur, à laquelle vous pouvez accéder tout en bas de la fenêtre de l'éditeur (faites glisser la poignée bleue vers le haut pour la rendre visible).
Vous pouvez maintenant pimenter vos nœuds avec une interface graphique. Ryven fonctionne sur Qt, en utilisant PySide2 ou PySide6 (via la bibliothèque qtpy). Vous pouvez configurer l'interface graphique de vos nœuds dans un fichier séparé et ajouter des widgets Qt personnalisés à vos nœuds. Assurez-vous de toujours séparer clairement la logique du nœud des composants de l'interface graphique. L'une des fonctionnalités centrales de Ryven est d'exécuter des projets sans tête (sur ryvencore) sans aucune dépendance GUI. Pour que cela fonctionne, vos fichiers nodes.py
ne doivent jamais dépendre directement de Qt. Au lieu de cela, vous pouvez attacher une interface graphique personnalisée à vos nœuds à partir des fichiers GUI, comme indiqué ci-dessous.
Donnons-leur un peu de couleur et ajoutons un slider au nœud Rand
, dans 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' }
}
et voilà ! Ryven va désormais enregistrer RandNodeGui
en tant que "classe GUI" de la classe RandNode
, qui sert de conteneur pour toutes les choses de l'interface utilisateur. Vous pouvez ajouter des widgets principaux (« principaux ») personnalisés à vos nœuds, des widgets d'entrée et personnaliser davantage l'apparence des nœuds.
La valeur fournie par un widget d'entrée (par exemple self.update_node_input(val)
ci-dessus) sera renvoyée dans le nœud, lors de l'appel à input()
(par exemple self.input(0)
dans le RandNode
), mais uniquement lorsque l'entrée correspondante n'est pas connecté . Sinon, la valeur de la sortie connectée sera renvoyée.
Veuillez trouver d'autres ressources sur la page wiki GitHub de ce référentiel.
Sauf indication contraire explicite de votre part, toute contribution que vous soumettez intentionnellement pour être incluse dans l'œuvre sera sous licence comme ci-dessus, sans termes ou conditions supplémentaires.
Les contributions sont très appréciées. Ce projet n'existe pas sans la communauté open source. Je tiens à remercier particulièrement les personnes répertoriées dans le fichier CREDITS.md
.