PySharp enthält eine Windows-Forms-Anwendung namens PyCross, die das Hosten von Python-Plugins innerhalb einer C#-Anwendung ermöglicht. Die App initialisiert einen eingebetteten Python-Runtime, lädt C#-Module als Python-API zur Laufzeit nach, generiert .pyi-Stubdateien und kann Plugins inklusive eigener GUI-Elemente und Event-Loops ausführen.
| Pfad | Inhalt |
|---|---|
PyCross.sln |
Visual-Studio-Solution mit einem Projekt (PyCross). |
PyCross/ |
C#-Projektdateien, Formulare und API-Code. |
LICENSE.txt |
MIT-Lizenztext des Projekts. |
Program.cs: Einstiegspunkt, startetForm1mittelsApplication.Runnach Standard-WinForms-Konfiguration.Form1.*: Enthält Oberfläche (Buttons, ListView, Log, TabControl), Eventhandler zum Laden/Ausführen von Plugins und Verwaltung des Python-Runtimes inklusive periodischer Event-Loops.
- Initialisierung (
Form1.InitPythonRuntime): setztPythonHomeauf das gebündeltePyRuntime, sucht die DLL, initialisiertPythonEngineund exportiert registrierte C#-Plugin-Methoden als Python-Modulpycross. Zusätzlich wird die GUI-API (WFAPI.GUI) in das Modul injiziert. - Plugin-Lifecycle:
ModuleLoader.InitAll(this)sucht zur Laufzeit alleIPythonPlugin-Implementierungen, ruftInit(Form1)auf und speichert sie im Dictionary für spätere Abfragen.LoadPythonPluginslistet.py-Dateien im OrdnerPlugins(neben dem Projekt) auf und füllt die ListView.RunPythonPluginlädt das ausgewählte Skript viaimportlibals Modul und merkt es sich in_loadedPluginsfür Event-Loops und Events.StartPluginEventLoopnutzt einenPeriodicTimer, um regelmäßigplugin.event_loop()aufzurufen, sofern implementiert.button3_Clickdemonstriert das Triggern eines generischenevents-Callbacks aller Plugins.
- Designer-Datei erstellt eine Steuerleiste mit Buttons (
Plugin laden,Plugin ausführen,Event), eine Plugin-Liste, ein Log und einTabControlfür plugin-spezifische Seiten. DieWFAPI-GUI-API hängt diese Controls an dieTabPagesan.
Die API ist modular aufgebaut; jedes Modul implementiert IPythonPlugin und wird vom ModuleLoader registriert.
Interface/IPythonPlugin.cs: definiertModuleNameundInit(Form1)als verpflichtende Elemente für alle Plugins.
ModuleLoader/ModuleLoader.cs: reflektiert alle Assemblies nachIPythonPlugin, instanziiert sie, ruftInit, loggt das Laden und stellt Zugriff überGet(module)undGetAll()bereit.ModuleLoader/PythonPlugin.cs: liefert Python-freundliche Zugriffsfunktionenget()undall()auf die registrierten Plugins.ModuleLoader/StubGenerator.cs: generiert.pyi-Stubdateien mit folgenden Anteilen:- alle öffentlichen Methoden der Plugins als top-level Funktionen (mit Typ-Mapping C# → Python),
- eine Klasse
GUIbasierend auf der verschachtelten KlasseWFAPI.GUI, - Wrapper-Klassen für alle
GuiControlWrapper-Ableitungen (Label-, Button-, CheckBox-, TextBox-, ComboBoxWrapper).
Core/CoreAPI: stellt Logging, allgemeine Info-/Charakterdaten sowiestart/stop-Methoden bereit, indem es die anInitübergebeneForm1nutzt.Inventory/InventoryAPI: bietet einRefresh-Log, sowieMoveItem, das beispielhaft einPyDictzurückliefert (Slots, Menge).
GUI/API.Gui.cs: implementiertWFAPI, das pro Plugin TabPages erzeugt und Controls verwaltet.- Innere Klasse
GUI: dient als API, die Python-Plugins instanziieren, um Label, Button, CheckBox, TextBox und ComboBox zu erzeugen. Jede Methode liefert einen Wrapper zurück und registriert das Control. - Methoden wie
ClearAllControls,DeleteAllPagesundResetAllermöglichen das Zurücksetzen der GUI.
- Innere Klasse
GUI/Controls: enthält konkrete Wrapper (Label/Button/CheckBox/TextBox/ComboBox), dieGuiControlWrappererweitern. Diese Wrapper kapseln Zugriff auf WinForms-Controls (Thread-sichere Setter, Event-Bindings zu Python-Callbacks).GUI/Wrapper/API.Gui.Wrapper.cs: BasisklasseGuiControlWrappermit Hilfsmethoden für Sichtbarkeit, Text, Enabled-State und Position.
Handler/PythonErrorHandler.cs: formatiertPythonException-Infos mit Kopfzeile und Stacktrace.HotReload/HotReload.cs: FileSystemWatcher für den Plugins-Ordner, loggt Änderungen und lädt Module viaimportlib.reload. Geplante GUI-Reset-Integration ist kommentiert.
- Plugins-Verzeichnis:
Form1erwartet einen OrdnerPluginsim Projektstamm. Beim ersten Laden wird er erstellt;.py-Dateien dienen als Plugins. - Python-Laufzeit: Die Anwendung sucht eine
python31*.dllim OrdnerPyRuntime. Ohne diese wird ein Log-Eintrag erzeugt, aber keine Initialisierung. - Threading: Zugriff auf WinForms-Controls erfolgt stets über
Invoke, sowohl inForm1(Log, Control-Updates) als auch in den GUI-Wrappern, um Cross-Thread-Aufrufe zu vermeiden. - Event-Loops: Plugins dürfen optionale Methoden
event_loopundevents(args)bereitstellen; beide werden zyklisch bzw. auf Button-Klick getriggert. - Stub-Generierung:
PythonStubGenerator.Generatewird im Form-Konstruktor mit dem ZielPlugins/pycross.pyiaufgerufen. So verfügen Plugin-Autoren über IntelliSense/Typinformationen. - HotReload:
PythonPluginHotReload.Startist vorbereitet, aber aktuell im UI auskommentiert. Aktiviert man den Aufruf, reagiert die App auf Dateiänderungen mit Reload und Log-Ausgaben.