1. Was ist GladeVCP?

GladeVCP ist eine LinuxCNC-Komponente, welche die Fähigkeit, eine neue Schaltfläche (engl. panel) auf LinuxCNC Benutzeroberflächen hinzuzufügen wie:

  • ACHSE

  • Touchy

  • Gscreen

  • GMOCCAPY

Im Gegensatz zu PyVCP ist GladeVCP nicht auf die Anzeige und Einstellung von HAL-Pins beschränkt, da beliebige Aktionen in Python-Code ausgeführt werden können - tatsächlich könnte eine komplette LinuxCNC-Benutzeroberfläche mit GladeVCP und Python erstellt werden.

GladeVCP verwendet den Glade WYSIWYG-Benutzeroberflächen-Editor, der es einfach macht, visuell ansprechende Panels zu erstellen. Es stützt sich auf die PyGObject-Bindungen an den umfangreichen GTK3-Widgetsatz, und tatsächlich können alle diese Widgets in einer GladeVCP-Anwendung verwendet werden - nicht nur die speziellen Widgets für die Interaktion mit HAL und LinuxCNC, die hier dokumentiert sind.

1.1. PyVCP im Vergleich zu GladeVCP auf einen Blick

Beide unterstützen die Erstellung von Panels mit "HAL Widgets" - Benutzeroberfläche Elemente wie LED’s, Tasten, Schieberegler usw., deren Werte zu einem HAL-Pin, die wiederum Schnittstellen zu den Rest von LinuxCNC verbunden sind.

PyVCP:

  • Widget-Set: verwendet TkInter-Widgets.

  • Erstellung der Benutzeroberfläche: Zyklus "XML-Datei bearbeiten / Ergebnis ausführen / Aussehen auswerten".

  • Keine Unterstützung für die Einbettung benutzerdefinierter Ereignisbehandlung.

  • Keine LinuxCNC Interaktion über HAL Pin I/O hinaus unterstützt.

GladeVCP:

  • Widgetsatz: stützt sich auf den GTK3-Widgetsatz.

  • Erstellung von Benutzeroberflächen: verwendet den Glade WYSIWYG-Editor für Benutzeroberflächen.

  • Jede HAL-Pin-Änderung kann für einen Callback und damit einen benutzerdefinierten Python-Ereignishandler genutzt werden.

  • Jedes GTK-Signal (Tastendruck, Fenster-, E/A-, Timer-, Netzwerkereignisse) kann mit benutzerdefinierten Handlern in Python verknüpft werden.

  • Direkte LinuxCNC-Interaktion: beliebige Befehlsausführung, wie das Auslösen von MDI-Befehlen, um ein G-Code-Unterprogramm aufzurufen, sowie Unterstützung für Statuswechseloperationen durch Action Widgets.

  • Mehrere unabhängige GladeVCP-Panels können in verschiedenen Registerkarten ausgeführt werden.

  • Trennung von Aussehen und Funktionalität der Benutzeroberfläche: Änderung des Aussehens ohne Eingriff in den Code.

2. Ein kurzer Rundgang mit dem Beispielpanel

Die GladeVCP-Panel-Fenster können in drei verschiedenen Konfigurationen betrieben werden:

  • immer sichtbar, integriert in AXIS auf der rechten Seite, genau wie PyVCP-Panels,

  • als Registerkarte in AXIS, Touchy, Gscreen oder GMOCCAPY; in AXIS würde dies eine dritte Registerkarte neben den Registerkarten Vorschau und DRO erzeugen, die explizit angehoben werden müssen,

  • als eigenständiges Toplevel-Fenster, das unabhängig vom Hauptfenster ikonifiziert/deikonifiziert werden kann.

Installiertes LinuxCNC

Wenn Sie eine installierte Version von LinuxCNC verwenden, sind die unten gezeigten Beispiele in der configuration picker in der Sample Configurations > apps > GladeVCP Zweig.

Git-Checkout

Die folgenden Anweisungen gelten nur, wenn Sie einen Git-Checkout verwenden. Öffnen Sie ein Terminal, wechseln Sie in das von git erstellte Verzeichnis und geben Sie dann die angezeigten Befehle ein.

Anmerkung
Damit die folgenden Befehle bei Ihrem Git-Checkout funktionieren, müssen Sie zuerst make ausführen, dann sudo make setuid und dann . ./scripts/rip-environment. Weitere Informationen über einen Git-Checkout finden Sie auf der LinuxCNC-Wiki-Seite.

Führen Sie das in AXIS integrierte GladeVCP-Beispielpanel wie PyVCP wie folgt aus:

$ cd configs/sim/axis/gladevcp
$ linuxcnc gladevcp_panel.ini
images/example-panel-small.png

Führen Sie das gleiche Panel aus, aber als Registerkarte innerhalb von AXIS:

$ cd configs/sim/axis/gladevcp
$ linuxcnc gladevcp_tab.ini
images/example-tabbed-small.png

Um dieses Panel innerhalb von Touchy auszuführen:

$ cd configs/sim/touchy/gladevcp
$ linuxcnc gladevcp_touchy.ini
images/touchy-tab-33.png

Funktional sind diese Setups identisch - sie unterscheiden sich nur in den Anforderungen an die Bildschirmfläche und die Sichtbarkeit. Da es möglich ist, mehrere GladeVCP-Komponenten parallel laufen zu lassen (mit unterschiedlichen HAL-Komponentennamen), sind auch gemischte Setups möglich - zum Beispiel ein Panel auf der rechten Seite und eine oder mehrere Registerkarten für weniger häufig genutzte Teile der Oberfläche.

2.1. Erkunden des Beispielpanels

Wenn Sie configs/sim/axis/gladevcp_panel.ini oder configs/sim/axis/gladevcp_tab.ini aufrufen, erkunden Sie Zeige HAL Konfiguration (engl. Show HAL Configuration) - Sie finden die gladevcp-HAL-Komponente und können ihre Pin-Werte beobachten, während Sie mit den Widgets im Panel interagieren. Die HAL-Konfiguration ist in configs/axis/gladevcp/manual-example.hal zu finden.

Das Beispiel-Panel hat zwei Rahmen am unteren Rand. Das Bedienfeld ist so konfiguriert, dass das Zurücksetzen des Notaus (engl. ESTOP) den Rahmen "Einstellungen" aktiviert und das Einschalten der Maschine den Rahmen "Befehle" im unteren Bereich aktiviert. Die HAL-Widgets im Rahmen "Einstellungen" sind mit den LEDs und Beschriftungen im Rahmen "Status" sowie mit der aktuellen und vorbereiteten Werkzeugnummer verknüpft - spielen Sie mit ihnen, um die Wirkung zu sehen. Wenn Sie die Befehle T<Werkzeugnummer> und M6 im MDI-Fenster ausführen, werden die Felder für die aktuelle und die vorbereitete Werkzeugnummer geändert.

Die Buttons im Rahmen "Befehle" (engl. Commands) sind MDI-Aktions-Widgets - wenn Sie sie drücken, wird ein MDI-Befehl im Interpreter ausgeführt. Der dritte Button "Oword-Unterprogramm ausführen" (engl. Execute Oword subroutine) ist ein fortgeschrittenes Beispiel - dieser übernimmt mehrere HAL-Pin-Werte aus dem Rahmen Einstellungen (engl. Settings) und übergibt sie als Parameter an das Oword-Unterprogramm. Die tatsächlichen Parameter der Routine werden durch (DEBUG, ) Befehle angezeigt - siehe ../../nc_files/oword.ngc für den Unterprogrammkörper.

Um zu sehen, wie das Panel in AXIS integriert ist, sehen Sie die Anweisung [DISPLAY]GLADEVCP in configs/sim/axis/gladevcp/gladevcp_panel.ini, die Anweisung [DISPLAY]EMBED* in configs/sim/axis/gladevcp/gladevcp_tab.ini und [HAL]POSTGUI_HALFILE sowohl in configs/sim/axis/gladevcp/gladevcp_tab.ini als auch in configs/sim/axis/gladevcp/gladevcp_panel.ini.

2.2. Erkunden der Beschreibung der Benutzeroberfläche

Die Benutzeroberfläche wird mit dem Glade UI-Editor erstellt - um sie zu erkunden, müssen Sie Glade installiert haben. Um die Benutzeroberfläche zu bearbeiten, nutzen Sie den Befehl

$ glade configs/axis/gladevcp/manual-example.ui

Das erforderliche glade-Programm kann auf neueren Systemen den Namen glade-gtk2 tragen.

Das mittlere Fenster zeigt das Aussehen der Benutzeroberfläche. Alle Objekte der Benutzeroberfläche und Unterstützungsobjekte befinden sich im rechten oberen Fenster, in dem Sie ein bestimmtes Widget auswählen können (oder indem Sie es im mittleren Fenster anklicken). Die Eigenschaften des ausgewählten Widgets werden im rechten unteren Fenster angezeigt und können dort geändert werden.

Um zu sehen, wie MDI-Befehle von den MDI-Aktions-Widgets weitergegeben werden, erkunden Sie die Widgets, die unter "Aktionen" im Fenster oben rechts aufgeführt sind, und im Fenster unten rechts unter der Registerkarte "Allgemein" die Eigenschaft "MDI-Befehl".

2.3. Erkunden der Python Callback Funktionen

Sehen Sie, wie ein Python-Callback in das Beispiel integriert wird:

  • In Glade siehe das hits Label Widget (ein einfaches GTK+ Widget).

  • Im Widget button1 auf der Registerkarte "Signale" das Signal "gedrückt" suchen, das mit dem Handler "on_button_press" verknüpft ist.

  • In hitcounter.py sehen Sie sich die Methode on_button_press an und sehen, wie sie die Eigenschaft label im Objekt hits setzt.

Dies ist nur ein kurzer Überblick über das Konzept - der Callback-Mechanismus wird im Abschnitt GladeVCP Programming ausführlicher behandelt.

3. Erstellen und Integrieren einer Glade-Benutzeroberfläche

3.1. Voraussetzung ist: Glade-Installation

Um Glade UI Dateien anzuzeigen oder zu verändern, muss Glade 3.38.2 oder höher installiert sein - es wird nicht benötigt, um ein GladeVCP Panel zu starten. Wenn der Befehl glade fehlt, installieren Sie ihn mit dem Befehl:

$ sudo apt install glade

Überprüfen Sie dann die installierte Version, die gleich oder höher als 3.6.7 sein muss:

$ glade --version

Glade enthält einen internen Python-Interpreter, und es wird nur Python3 unterstützt. Dies gilt für Debian Bullseye, Ubuntu 21 und Mint 21 oder später. Ältere Versionen werden nicht funktionieren, Sie werden einen Python-Fehler erhalten.

3.2. Glade ausführen, um eine neue Benutzeroberfläche zu erstellen

Dieser Abschnitt umreißt nur die ersten LinuxCNC-spezifischen Schritte. Weitere Informationen und eine Anleitung zu Glade finden Sie unter https://glade.gnome.org. Einige Tipps und Tricks zu Glade finden Sie auch auf youtube.

Ändern Sie entweder eine bestehende UI-Komponente, indem Sie glade <Datei>.ui ausführen, oder starten Sie eine neue, indem Sie einfach den Befehl glade in der Shell ausführen.

  • Wenn LinuxCNC nicht aus einem Paket installiert wurde, muss die LinuxCNC-Shell-Umgebung mit source <linuxcncdir>/scripts/rip-environment eingerichtet werden, sonst findet Glade die LinuxCNC-spezifischen Widgets nicht.

  • Wenn Sie nach nicht gespeicherten Einstellungen gefragt werden, akzeptieren Sie einfach die Standardeinstellungen und klicken Sie auf „Schließen“.

  • Wählen Sie in der Symbolleiste "Toplevels" "GtkWindow" (erster Eintrag) als Fenster der obersten Ebene. Legen Sie window1 als ID im rechten Fensterbereich unter der Registerkarte Allgemeines (engl. General) fest. Diese Benennung ist wichtig, weil GladeVCP sich darauf verlässt.

  • Über die Schaltfläche mit den drei Punkten können Sie die LinuxCNC-spezifischen Widgets finden.

  • Fügen Sie einen Container wie eine HAL_Box oder eine HAL_Table aus HAL Python in den Rahmen ein.

  • Wählen Sie einige Elemente wie LEDs, Schaltflächen usw. aus und platzieren Sie sie in einem Container.

Dies wird folgendermaßen aussehen:

images/glade-manual-small.png

Glade neigt dazu, eine Menge Meldungen in das Shell-Fenster zu schreiben, die meist ignoriert werden können. Wählen Sie "Datei→Speichern unter", geben Sie der Datei einen Namen wie "myui.ui" und stellen Sie sicher, dass sie als "GtkBuilder"-Datei gespeichert wird (Optionsfeld links unten im Speichern-Dialog). GladeVCP verarbeitet auch das ältere libglade-Format korrekt, aber es hat keinen Sinn, es zu verwenden. Die Konvention für die GtkBuilder-Dateierweiterung ist .ui.

3.3. Testen eines Panels

Sie sind jetzt bereit, es auszuprobieren (während LinuxCNC, z. B. AXIS läuft) mit:

gladevcp myui.ui

GladeVCP erstellt eine HAL-Komponente mit dem Namen des Basisnamens der UI-Datei - in diesem Fall myui - es sei denn, sie wird mit der Option -c <Komponentenname> überschrieben. Wenn AXIS läuft, versuchen Sie einfach Show HAL configuration und untersuchen Sie die Pins.

Sie fragen sich vielleicht, warum Widgets, die in einer HAL_Hbox oder HAL_Table enthalten sind, ausgegraut (inaktiv) erscheinen. HAL-Container haben einen zugehörigen HAL-Pin, der standardmäßig ausgeschaltet ist, so dass alle enthaltenen Widgets inaktiv dargestellt werden. Ein üblicher Anwendungsfall wäre, diese Container-HAL-Pins mit halui.machine.is-on oder einem der halui.mode-Signale zu verknüpfen, um sicherzustellen, dass einige Widgets nur in einem bestimmten Zustand aktiv erscheinen.

Um nur einen Container zu aktivieren, führen Sie den HAL-Befehl setp gladevcp.<container-name> 1 aus.

3.4. Vorbereiten der HAL-Befehlsdatei

Die vorgeschlagene Methode zur Verknüpfung von HAL-Pins in einem GladeVCP-Panel besteht darin, sie in einer separaten Datei mit der Erweiterung .hal zu sammeln. Diese Datei wird über die Option POSTGUI_HALFILE= im Abschnitt HAL Ihrer INI-Datei übergeben.

Achtung
Fügen Sie die GladeVCP-HAL-Befehlsdatei nicht in den Abschnitt AXIS [HAL]HALFILE= ini ein, da dies nicht den gewünschten Effekt hat - siehe die folgenden Abschnitte.

3.5. Einbindung in AXIS, wie PyVCP

Platzieren Sie das GladeVCP-Panel im rechten Seitenbereich, indem Sie in der INI-Datei Folgendes angeben:

[DISPLAY]
# add GladeVCP panel where PyVCP used to live:
GLADEVCP= -u ./hitcounter.py ./manual-example.ui

[HAL]
# HAL-Befehle für GladeVCP-Komponenten in einer Registerkarte müssen über POSTGUI_HALFILE ausgeführt werden
POSTGUI_HALFILE = ./handbuch-beispiel.hal

[RS274NGC]
# gladevcp Demo-spezifische Oword-Subs leben hier
SUBROUTINE_PATH = ../../nc_files/gladevcp_lib

Der Standard-HAL-Komponentenname einer GladeVCP-Anwendung, die mit der Option GLADEVCP gestartet wird, lautet: gladevcp.

Die von AXIS in der obigen Konfiguration tatsächlich ausgeführte Befehlszeile lautet wie folgt:

halcmd loadusr -Wn gladevcp gladevcp -c gladevcp -x {XID} -u ./hitcounter.py ./manual-example.ui

Sie können hier beliebige gladevcp-Optionen hinzufügen, solange sie nicht mit den obigen Kommandozeilenoptionen kollidieren.

Es ist möglich, einen benutzerdefinierten HAL-Komponentennamen zu erstellen, indem Sie die Option -c hinzufügen:

[DISPLAY]
# fügen Sie das GladeVCP-Panel an der Stelle ein, an der früher PyVCP stand:
GLADEVCP= -c example -u ./hitcounter.py ./manual-example.ui

Die Befehlszeile, die von AXIS für die obigen Schritte ausgeführt wird, lautet:

halcmd loadusr -Wn example gladevcp -c example -x {XID} -u ./hitcounter.py ./manual-example.ui
Anmerkung
Die Dateispezifikationen wie ./hitcounter.py, ./manual-example.ui usw. bedeuten, dass sich die Dateien im selben Verzeichnis wie die INI-Datei befinden. Möglicherweise müssen Sie sie in Ihr Verzeichnis kopieren (oder einen korrekten absoluten oder relativen Pfad zu der/den Datei(en) angeben).
Anmerkung
Die Option [RS274NGC]SUBROUTINE_PATH= ist nur gesetzt, damit das Beispiel-Panel die Oword-Subroutine (oword.ngc) für das MDI Command Widget findet. Sie wird in Ihrem Setup möglicherweise nicht benötigt. Die relative Pfadangabe ../../nc_files/gladevcp_lib ist so konstruiert, dass sie mit Verzeichnissen funktioniert, die von der Konfigurationsauswahl kopiert wurden, und wenn ein Run-in-Place-Setup verwendet wird.

3.6. Einbetten als Registerkarte (engl. tab)

Bearbeiten Sie dazu Ihre INI-Datei und fügen Sie die Abschnitte DISPLAY und HAL der INI-Datei wie folgt hinzu:

[DISPLAY]
# GladeVCP-Panel als Registerkarte neben Vorschau/DRO hinzufügen:
EMBED_TAB_NAME=GladeVCP demo
EMBED_TAB_COMMAND=halcmd loadusr -Wn gladevcp gladevcp -c gladevcp -x {XID} -u ./gladevcp/hitcounter.py ./gladevcp/manual-example.ui

[HAL]
# HAL-Befehle für GladeVCP-Komponenten in einer Registerkarte müssen über POSTGUI_HALFILE ausgeführt werden
POSTGUI_HALFILE = ./gladevcp/manual-example.hal

[RS274NGC]
# gladevcp Demo-spezifische Oword-Subs leben hier
SUBROUTINE_PATH = ../../nc_files/gladevcp_lib

Beachten Sie die halcmd loadusr-Art, den Tab-Befehl zu starten - dies stellt sicher, dass POSTGUI_HALFILE erst ausgeführt wird, nachdem die HAL-Komponente fertig ist. In seltenen Fällen können Sie hier einen Befehl ausführen, der eine Registerkarte verwendet, aber keine HAL-Komponente zugeordnet ist. Ein solcher Befehl kann ohne halcmd loadusr gestartet werden, und dies bedeutet für AXIS, dass es nicht auf eine HAL-Komponente warten muss, da es keine gibt.

Beim Ändern des Komponentennamens im obigen Beispiel ist zu beachten, dass die in -Wn <Komponente> und -c <Komponente> verwendeten Namen identisch sein müssen.

Probieren Sie es aus, indem Sie AXIS starten - es sollte eine neue Registerkarte mit dem Namen "GladeVCP demo" in der Nähe der Registerkarte "DRO" erscheinen. Wählen Sie diese Registerkarte, sollten Sie das Beispiel-Panel schön innerhalb von AXIS passen zu sehen.

Anmerkung
Stellen Sie sicher, dass die UI-Datei die letzte Option ist, die an GladeVCP in den Anweisungen GLADEVCP= und EMBED_TAB_COMMAND= übergeben wird.

3.7. Integration in Touchy

Um eine GladeVCP-Registerkarte zu "Touchy" hinzuzufügen, bearbeiten Sie Ihre INI-Datei wie folgt:

[DISPLAY]
# GladeVCP-Panel als Registerkarte hinzufügen
EMBED_TAB_NAME=GladeVCP-Demo
EMBED_TAB_COMMAND=gladevcp -c gladevcp -x {XID} -u ./hitcounter.py -H ./gladevcp-touchy.hal ./manual-example.ui

[RS274NGC]
# gladevcp Demo-spezifische Oword-Subs leben hier
SUBROUTINE_PATH = ../../nc_files/gladevcp_lib
Anmerkung
Die Dateispezifikationen wie ./hitcounter.py, ./manual-example.ui usw. bedeuten, dass sich die Dateien im selben Verzeichnis wie die INI-Datei befinden. Möglicherweise müssen Sie sie in Ihr Verzeichnis kopieren (oder einen korrekten absoluten oder relativen Pfad zu der/den Datei(en) angeben).

Beachten Sie die folgenden Unterschiede zur Einrichtung der Registerkarte von AXIS:

  • Die HAL-Befehlsdatei ist leicht modifiziert, da Touchy die halui-Komponenten nicht verwendet, so dass seine Signale nicht verfügbar sind und einige Verknüpfungen verwendet wurden.

  • Es gibt keine INI-Option POSTGUI_HALFILE=, aber die Übergabe der HAL-Befehlsdatei in der Zeile EMBED_TAB_COMMAND= ist in Ordnung.

  • Die Beschwörungsformel "halcmd loaduser -Wn …" ist nicht erforderlich.

4. GladeVCP-Befehlszeilenoptionen

Siehe auch man gladevcp. Dies sind die GladeVCP-Kommandozeilenoptionen:

Usage: gladevcp [options] myfile.ui

Optionen:

-h, --help::
    Show this help message and exit.

-c NAME::
    Setzt den Komponentennamen auf NAME. Standard ist der Basisname der UI-Datei.

-d::
    Debug-Ausgabe einschalten

-g GEOMETRIE::
    Legt die Geometrie WIDTHxHEIGHT+XOFFSET+YOFFSET fest. Die Werte sind in Pixel-Einheiten, XOFFSET/YOFFSET wird vom linken oberen Bildschirmrand aus referenziert.
    Verwenden Sie -g WIDTHxHEIGHT, um nur die Größe zu bestimmen, oder -g +XOFFSET+YOFFSET, um nur Position zu bestimmen.

-H DATEI::
    Führt HAL-Anweisungen aus DATEI mit halcmd aus, nachdem die Komponente eingerichtet und bereit ist

-m MAXIMUM::
    Erzwingt die Maximierung des Panel-Fensters.
    Zusammen mit der Option -g geometry kann man das Panel auf einen zweiten Monitor verschieben und es zwingen, den gesamten Bildschirm zu nutzen.

-t THEME::
    Setzt das gtk-Theme. Standard ist das Systemthema. Verschiedene Panels können unterschiedliche Themen haben.

-x XID::
    GladeVCP in ein bestehendes Fenster XID einbinden, anstatt eines neuen Fensters der obersten Ebene

-u FILE::
    Dateien als zusätzliche benutzerdefinierte Module mit Handlern verwenden

-U USEROPT::
    übergibt USEROPTs an Python-Module

5. Den GladeVCP-Startvorgang verstehen

Die oben beschriebenen Integrationsschritte sehen ein wenig kompliziert aus, und das sind sie auch. Es ist daher hilfreich, den Startvorgang von LinuxCNC zu verstehen und wie sich dieser auf GladeVCP bezieht.

Der normale Startvorgang von LinuxCNC macht folgendes:

  • Die Echtzeitumgebung wird gestartet.

  • Alle HAL-Komponenten werden geladen.

  • Die HAL-Komponenten sind durch die .hal cmd-Skripte miteinander verbunden.

  • task, iocontrol und schließlich wird die Benutzeroberfläche gestartet.

  • Vor der Einführung von GladeVCP wurde davon ausgegangen, dass zu dem Zeitpunkt, zu dem die Benutzeroberfläche gestartet wird, die gesamte HAL geladen, verkabelt und einsatzbereit ist.

Die Einführung von GladeVCP brachte das folgende Problem mit sich:

  • GladeVCP-Panels müssen in ein übergeordnetes GUI-Fenster eingebettet werden.

  • GladeVCP-Panels müssen in ein übergeordnetes GUI-Fenster eingebettet werden, z.B. AXIS, oder Touchy, Gscreen, oder GMOCCAPY (eingebettetes Fenster oder als eingebettete Registerkarte).

  • Dies erfordert, dass die Master-GUI läuft, bevor das GladeVCP-Fenster in die Master-GUI eingehängt werden kann.

  • GladeVCP ist jedoch auch eine HAL-Komponente und erzeugt eigene HAL-Pins.

  • Als Folge davon müssen alle HAL-Pins, die GladeVCP HAL-Pins als Quelle oder Ziel verwenden, nach der Einrichtung der GUI ausgeführt werden.

Dies ist der Zweck der Option POSTGUI_HALFILE. Diese INI-Option wird von den GUIs überprüft. Wenn ein GUI diese Option erkennt, führt es die entsprechende HAL-Datei aus, nachdem ein eingebettetes GladeVCP-Panel eingerichtet wurde. Es wird jedoch nicht geprüft, ob ein GladeVCP-Panel tatsächlich verwendet wird, in diesem Fall wird die HAL cmd-Datei einfach normal ausgeführt. Wenn man also GladeVCP nicht über GLADEVCP oder EMBED_TAB usw. startet, sondern später in einem separaten Shell-Fenster oder einem anderen Mechanismus, wird eine HAL-Befehlsdatei in POSTGUI_HALFILE zu früh ausgeführt. Unter der Annahme, dass hierin GladeVCP-Pins referenziert werden, wird dies mit einer Fehlermeldung fehlschlagen, die anzeigt, dass die GladeVCP-HAL-Komponente nicht verfügbar ist.

Falls Sie also GladeVCP von einem separaten Shell-Fenster aus starten (d.h. nicht von der GUI eingebettet gestartet):

  • Sie können sich nicht darauf verlassen, dass die INI-Option "POSTGUI_HALFILE" dazu führt, dass die HAL-Befehle "zum richtigen Zeitpunkt" ausgeführt werden, also kommentieren Sie sie in der INI-Datei aus.

  • Übergeben Sie die HAL-Befehlsdatei, die auf GladeVCP-Pins verweist, explizit an GladeVCP mit der Option -H <halcmd file> (siehe vorheriger Abschnitt).

6. HAL Widget-Referenz

GladeVCP enthält eine Sammlung von Gtk-Widgets mit angehängten HAL-Pins, genannt HAL-Widgets, die zur Steuerung, Anzeige oder anderweitigen Interaktion mit der LinuxCNC-HAL-Schicht gedacht sind. Sie sind für die Verwendung mit dem Glade-Benutzerschnittstellen-Editor vorgesehen. Bei ordnungsgemäßer Installation sollten die HAL Widgets in der Widget-Gruppe "HAL Python" von Glade auftauchen. Viele HAL-spezifische Felder im Glade-Abschnitt "Allgemein" haben einen zugehörigen Tooltip, wenn man mit der Maus darüber fährt.

HAL-Signale gibt es in zwei Varianten: Bits und Zahlen. Bits sind Aus/Ein-Signale. Zahlen können "float", "s32" oder "u32" sein. Für weitere Informationen über HAL-Datentypen siehe HAL Handbuch. Die GladeVCP-Widgets können entweder den Wert des Signals mit einem Indikator-Widget anzeigen oder den Signalwert mit einem Kontroll-Widget verändern. Es gibt also vier Klassen von GladeVCP-Widgets, die Sie mit einem HAL-Signal verbinden können. Eine weitere Klasse von Hilfs-Widgets ermöglicht es Ihnen, Ihr Panel zu organisieren und zu beschriften.

6.1. Benennung von Widgets und HAL-Pins

Die meisten HAL-Widgets haben einen einzigen zugehörigen HAL-Pin mit demselben HAL-Namen wie das Widget (glade: General→Name).

Ausnahmen von dieser Regel sind derzeit:

  • HAL_Spinbutton' und HAL_ComboBox, die zwei Pins haben: einen <widgetname>-f (float) und einen <widgetname>-s (s32) Pin

  • HAL_ProgressBar', die einen <widgetname>-value-Eingangspin und einen <widgetname>-scale-Eingangspin hat.

6.2. Python-Attribute und Methoden von HAL Widgets

HAL-Widgets sind Instanzen von GtKWidgets und erben daher die Methoden, Eigenschaften und Signale der entsprechenden GtkWidget-Klasse. Um z.B. herauszufinden, welche GtkWidget-bezogenen Methoden, Eigenschaften und Signale ein HAL_Button hat, sehen Sie in der Beschreibung von GtkButton in der PyGObject API Reference nach.

Ein einfacher Weg, um die Vererbungsbeziehung eines bestimmten HAL-Widgets herauszufinden, ist folgender: Starten Sie Glade, platzieren Sie das Widget in einem Fenster und wählen Sie es aus; wählen Sie dann die Registerkarte Signale im Fenster Eigenschaften. Wenn Sie zum Beispiel ein HAL_LED-Widget auswählen, wird dies zeigen, dass ein HAL_LED von einem GtkWidget abgeleitet ist, welches wiederum von einem GtkObject und schließlich einem GObject abgeleitet ist.

Die vollständige Klassenhierarchie kann durch Aufrufen des GtkInspectors in der Glade-GUI eingesehen werden, indem man ein Widget auswählt und dann Control-Shift-I drückt. Wenn sich der Inspector nicht öffnet, kann er von einem Terminal aus durch Eingabe von:

gsettings set org.gtk.Settings.Debug enable-inspector-keybinding true

Der Inspektor ist auch praktisch, um CSS-Stiländerungen "on the fly" zu testen und alle für ein Widget verfügbaren Eigenschaften und Signale zu ermitteln.

HAL-Widgets haben auch einige HAL-spezifische Python-Attribute:

hal_pin

Das zugrundeliegende HAL-Pin-Python-Objekt, falls das Widget einen einzigen Pin-Typ hat

hal_pin_s, hal_pin_f

Die s32- und float-Pins der Widgets HAL_Spinbutton und HAL_ComboBox - beachten Sie, dass diese Widgets kein Attribut hal_pin haben!

hal_pin_scale

Der Float-Eingangs-Pin des Widgets "HAL_ProgressBar", der den maximalen absoluten Wert des Eingangs darstellt.

Es gibt mehrere HAL-spezifische Methoden von HAL Widgets, aber die einzige relevante Methode ist:

<halpin>.get()

Abrufen des Wertes des aktuellen HAL-Pins, wobei <halpin> der oben aufgeführte zutreffende HAL-Pinname ist.

6.3. Einstellung von Pin- und Widget-Werten

Als allgemeine Regel gilt: Wenn Sie den Wert eines HAL-Ausgabe-Widgets von Python-Code aus setzen müssen, tun Sie dies, indem Sie den zugrundeliegenden Gtk-Setter (z.B. set_active(), set_value()) aufrufen . Versuchen Sie nicht, den Wert des zugehörigen Pins direkt durch halcomp[pinname] = value zu setzen, da das Widget die Änderung nicht zur Kenntnis nimmt!

Es mag verlockend sein, HAL-Widget-Eingangs-Pins programmatisch zu setzen. Beachten Sie, dass dies den Zweck eines Eingangspins von vornherein zunichte macht - er sollte mit anderen HAL-Komponenten verknüpft sein und auf von ihnen erzeugte Signale reagieren. Da es derzeit keinen Schreibschutz für das Schreiben auf Input-Pins in HAL Python gibt, macht dies keinen Sinn. Zum Testen können Sie aber setp _pinname_ _value_ in der zugehörigen HAL-Datei verwenden.

Es ist völlig in Ordnung, den Wert eines Ausgangs-HAL-Pins mit halcomp[pinname] = value zu setzen, vorausgesetzt, dieser HAL-Pin ist nicht mit einem Widget verbunden, d.h. er wurde mit der Methode hal_glib.GPin(halcomp.newpin(<name>,<type>,<direction>)) erstellt (siehe GladeVCP Programming für ein Beispiel).

6.4. Das hal-pin-changed-Signal

Ereignisgesteuerte Programmierung bedeutet, dass die Benutzeroberfläche Ihrem Code mitteilt, wenn "etwas passiert" - durch einen Rückruf, z. B. wenn eine Taste gedrückt wurde. Die Ausgabe-HAL-Widgets (die den Wert eines HAL-Pins anzeigen) wie LED, Balken, VStabi, Zähler usw. unterstützen das Signal hal-pin-changed, das einen Callback in Ihrem Python-Code auslösen kann, wenn - nun ja, ein HAL-Pin seinen Wert ändert. Das bedeutet, dass es keine Notwendigkeit mehr gibt, HAL-Pin-Änderungen in Ihrem Code permanent abzufragen, die Widgets erledigen das im Hintergrund und informieren Sie darüber.

Hier ist ein Beispiel, wie man ein hal-pin-changed Signal für eine HAL_LED im Glade UI Editor setzt:

images/hal-pin-change-66.png

Das Beispiel in configs/apps/gladevcp/complex zeigt, wie dies in Python gehandhabt wird.

6.5. Buttons

Diese Gruppe von Widgets ist von verschiedenen Gtk-Buttons abgeleitet und besteht aus den Widgets HAL_Button, HAL_ToggleButton, HAL_RadioButton und CheckButton. Alle haben einen einzelnen BIT-Ausgangspin, der den gleichen Namen wie das Widget trägt. Buttons haben keine zusätzlichen Eigenschaften im Vergleich zu ihren Gtk-Basisklassen.

  • HAL_Button: Sofortige Aktion, behält den Zustand nicht bei. Wichtiges Signal: pressed (engl. für gedrückt)

  • HAL_ToggleButton, HAL_CheckButton: behält den Ein/Aus-Zustand bei. Wichtiges Signal: toggled (engl. für umgeschaltet)

  • HAL_RadioButton: eine "One-of-many"-Gruppe. Wichtiges Signal: toggled(umgeschaltet) (pro Button).

  • Wichtige gemeinsame Methoden: set_active(), get_active()

  • Wichtige Eigenschaften: label, image

images/checkbutton.png
Abbildung 1. Checkbutton
images/radiobutton.png
Abbildung 2. Radiobuttons
images/button.png
Abbildung 3. Toggle-Button
Tipp

Definieren von Optionsschaltflächengruppen in Glade:

  • Entscheiden Sie sich für einen aktiven Standardbutton.

  • Wählen Sie unter Allgemein→Gruppe der anderen Schaltfläche den Namen der standardmäßig aktiven Schaltfläche im Dialogfeld Wählen Sie eine Optionsschaltfläche in diesem Projekt.

Siehe configs/apps/gladevcp/by-widget/ für eine GladeVCP-Anwendung und UI-Datei für die Arbeit mit Optionsfeldern.

6.6. Skalen (engl. scales)

HAL_HScale und HAL_VScale sind von GtkHScale bzw. GtkVScale abgeleitet.

<widgetname>

out FLOAT pin

<widgetname>-s

out s32 pin

Um eine Skala in Glade nützlich zu machen, fügen Sie eine "Anpassung" hinzu (Allgemein → Anpassung → Neue oder bestehende Anpassung) und bearbeiten das Anpassungsobjekt. Es definiert die Standard-/Min-/Max-/Inkrementwerte. Setzen Sie außerdem die Anpassung Seitengröße und Seiteninkrement auf Null, um Warnungen zu vermeiden.

images/hscale.png
Abbildung 4. Beispiel HAL_HScale

6.7. SpinButton

HAL SpinButton ist von GtkSpinButton abgeleitet und besitzt zwei Pins:

<widgetname>-f

out FLOAT pin

<widgetname>-s

out s32 pin

Um nützlich zu sein, benötigen SpinButtons einen Einstellwert wie Skalen, siehe oben.

images/spinbutton.png
Abbildung 5. Beispiel SpinButton

6.8. Hal_Dial

Das hal_dial Widget simuliert ein Jogwheel oder ein Einstellrad.
Es kann mit der Maus bedient werden. Sie können einfach das Mausrad benutzen, während sich der Mauszeiger über dem Hal_Dial-Widget befindet, oder Sie halten die linke Maustaste gedrückt und bewegen den Mauszeiger in kreisförmiger Richtung, um die Zählungen zu erhöhen oder zu verringern.
Mit einem Doppelklick auf die linke oder rechte Taste kann der Skalierungsfaktor erhöht oder verringert werden.

  • Gegen den Uhrzeigersinn = kleinere Zählwerte

  • Clockwise = increase counts

  • Wheel up = increase counts

  • Wheel down = reduce counts

  • left Double Click = x10 scale

  • Right Double Click = /10 scale

6.8.1. Pins

hal_dial exportiert seinen Zählwert als HAL-Pins:

<widgetname>

out s32 pin

<widgetname>-scaled

out FLOAT pin

<widgetname>-delta-scaled

out FLOAT pin

6.8.2. Eigenschaften

hal_dial hat die folgenden Eigenschaften:

cpr

Legt die Anzahl der Zählungen pro Umdrehung fest, zulässige Werte liegen im Bereich von 25 bis 360 +
Voreinstellung = 100

show_counts

Setzen Sie diesen Wert auf False, wenn Sie die Anzeige der Zählerstände in der Mitte des Widgets ausblenden möchten. +
Standard = True

label

Legen Sie den Inhalt der Beschriftung fest, die über dem Zählwert angezeigt werden kann.
Ist die angegebene Beschriftung länger als 15 Zeichen, wird sie auf 15 Zeichen gekürzt.
Standard = leer

center_color

Damit kann man die Farbe des Rades ändern. Sie verwendet einen GDK-Farbstring. +
Standard = #bdefbdefbdef (grau)

count_type_shown

Es sind drei Zählungen verfügbar 0) Rohe CPR-Zählungen 1) Skalierte Zählungen 2) Delta-skalierte Zählungen. +
Standard = 1

  • Die Zählung basiert auf der gewählten CPR - sie zählt positiv und negativ. Er ist als s32-Pin verfügbar.

  • Der skalierte Zähler ist die CPR-Zahl mal der Skala - er kann positiv und negativ sein.
    Wenn Sie die Skala ändern, spiegelt der Ausgang die Änderung sofort wider. Er ist als FLOAT-Pin verfügbar.

  • Delta-scaled-count ist cpr count CHANGE, mal scale. +
    Wenn Sie die Skala ändern, werden nur die Zählerstände nach dieser Änderung skaliert und dann zum aktuellen Wert addiert. +
    Er ist als FLOAT-Pin verfügbar.

scale_adjustable

Setzen Sie diesen Wert auf False, wenn Sie Änderungen der Skalierung durch Doppelklick auf das Widget nicht zulassen wollen. +
Wenn dieser Wert auf False gesetzt ist, wird der Skalierungsfaktor im Widget nicht angezeigt. +
Standard = True

scale

Legen Sie diesen Wert fest, um die Zählungen zu skalieren. +
Standard = 1.0

6.8.3. Direkte Programmsteuerung

Es gibt Möglichkeiten, das Widget direkt mit Python zu steuern.

Verwenden Sie goobject, um die oben aufgeführten Eigenschaften einzustellen:

[widget name].set_property("cpr",int(value))
[widget name].set_property("show_counts, True)
[widget name].set_property("center_color",gtk.gdk.Color('#bdefbdefbdef'))
[widget name].set_property('label', 'Test Dial 12345')
[widget name].set_property('scale_adjustable', True)
[widget name].set_property('scale', 10.5)
[widget name].set_property('count_type_shown', 0)

Es gibt Python-Methoden:

  • [Widgetname].get_value()
    Gibt den Zählwert als s32-Ganzzahl zurück

  • [Widgetname].get_scaled_value()`
    Gibt den Zählwert als Gleitkommazahl zurück

  • [Widget-Name].get_delta_scaled_value() +
    Gibt den Counts-Wert als Gleitkommawert zurück

  • [Widgetname].set_label("string") +
    Setzt den Inhalt des Labels mit "string"

Es werden zwei GObject-Signale ausgegeben:

  • count_changed +
    Wird ausgesendet, wenn sich die Anzahl des Widgets ändert, z.B. wenn es mit dem Rad gescrollt wird.

  • scale_changed
    Wird ausgegeben, wenn sich der Maßstab des Widgets ändert, z. B. durch Doppelklick.

Schließen Sie diese wie folgt an:

[widget name].connect('count_changed', [count function name])
[widget name].connect('scale_changed', [scale function name])

Die Callback-Funktionen würden dieses Muster verwenden:

def [Name der Zählfunktion](widget, count,scale,delta_scale):

Dies gibt zurück: das Widget, die aktuelle Anzahl, Skalierung und Delta-Skalierung dieses Widgets.

images/Hal_Dial.png
Abbildung 6. Beispiel Hal_Dial

6.9. Jog-Handrad (engl. jog wheel)

Das Widget jogwheel simuliert ein echtes Jogwheel. Es kann mit der Maus bedient werden. Sie können einfach das Mausrad benutzen, während sich der Mauszeiger über dem JogWheel-Widget befindet, oder Sie drücken die linke Maustaste und bewegen den Mauszeiger in kreisförmiger Richtung, um die Zählungen zu erhöhen oder zu verringern.

  • Gegen den Uhrzeigersinn = kleinere Zählwerte

  • Clockwise = increase counts

  • Wheel up = increase counts

  • Wheel down = reduce counts

Da das Bewegen der Maus per Drag & Drop schneller sein kann, als das Widget sich selbst zu aktualisieren vermag, kann, dass Sie Zähler verlieren, wenn Sie zu schnell drehen. Es wird empfohlen, das Mausrad zu verwenden, und nur für sehr grobe Bewegungen die Drag-and-Drop-Methode.

6.9.1. Pins

jogwheel exportiert seinen Zählwert als HAL-Pin:

<widgetname>-s

out s32 pin

6.9.2. Eigenschaften

jogwheel hat folgende Eigenschaften:

Größe

Legt die Größe des Widgets in Pixeln fest; die zulässigen Werte liegen im Bereich von 100 bis 500 Standard = 200

cpr

Legt die Anzahl der Zählungen pro Umdrehung fest, zulässige Werte liegen im Bereich von 25 bis 100 Standard = 40

show_counts

Setzen Sie diesen Wert auf False, wenn Sie die Anzeige der Zählerstände in der Mitte des Widgets ausblenden möchten.

label

Legen Sie den Inhalt der Beschriftung fest, die über dem Zählwert angezeigt werden kann. Der Zweck ist, dem Benutzer eine Vorstellung über die Verwendung dieses Jogwheels zu geben. Wenn die Beschriftung länger als 12 Zeichen ist, wird sie auf 12 Zeichen gekürzt.

6.9.3. Direkte Programmsteuerung

Es gibt mehrere Möglichkeiten, das Widget direkt mit Python zu steuern.

Verwenden Sie GObject, um die oben aufgeführten Eigenschaften einzustellen:

[widget name].set_property("size",int(value))
[widget name].set_property("cpr",int(value))
[widget name].set_property("show_counts, True)

Es gibt zwei Python-Methoden:

  • [widget name].get_value()
    Gibt den Zählwert als Ganzzahl zurück

  • [Widgetname].set_label("string") +
    Setzt den Inhalt des Labels mit "string"

images/JogWheel.png
Abbildung 7. Beispiel JogWheel

6.10. Geschwindigkeitsregelung

speedcontrol ist ein Widget, das speziell für die Steuerung einer Einstellung über einen Touchscreen entwickelt wurde. Es ist ein Ersatz für das normale Skalen-Widget, das auf einem Touchscreen nur schwer zu verschieben ist.

Der Wert wird mit zwei Tasten zum Erhöhen oder Verringern des Wertes gesteuert. Die Schrittweite ändert sich, solange eine Schaltfläche gedrückt wird. Der Wert jedes Inkrements sowie die Zeit zwischen zwei Änderungen können über die Widgeteigenschaften eingestellt werden.

6.10.1. Pins

speedcontrol bietet einige HAL-Pins:

<widgetname>-value

out float pin +
Der angezeigte Wert des Widgets.

<widgetname>-scaled-value

out float pin +
Der angezeigte Wert geteilt durch den Skalenwert, ist dies sehr nützlich, wenn die Geschwindigkeit in Einheiten / min angezeigt wird, aber LinuxCNC erwartet, dass es in Einheiten / Sekunde sind.

<widgetname>-scale

in float pin +
Die anzuwendende Skalierung. +
Voreingestellt ist 60.

<widgetname>-increase

in Bit-Pin +
Solange der Pin wahr ist, erhöht sich der Wert. +
Sehr praktisch bei angeschlossenem Taster.

<widgetname>-decrease

in Bit-Pin
Solange der Pin wahr ist, wird der Wert verringert.
Sehr praktisch bei angeschlossenem Taster.

6.10.2. Eigenschaften

speedcontrol hat die folgenden Eigenschaften:

height (engl. für Höhe)

Integer +
Die Höhe des Widgets in Pixel. +
Erlaubte Werte sind 24 bis 96. +
Voreinstellung ist 36.

Wert

Gleitkommazahl +
Der einzustellende Startwert. +
Erlaubte Werte liegen im Bereich von 0,001 bis 99999,0. +
Standardwert ist 10,0.

min

Gleitkommazahl +
Der zulässige Mindestwert. +
Erlaubte Werte sind 0,0 bis 99999,0. +
Der Standardwert ist 0,0. +
Wenn Sie diesen Wert ändern, wird die Schrittweite auf den Standardwert zurückgesetzt, so dass es notwendig sein kann, anschließend eine neue Schrittweite festzulegen.

max

Gleitkommazahl
Der maximal zulässige Wert.
Erlaubte Werte sind 0,001 bis 99999,0.
Der Standardwert ist 100,0.
Wenn Sie diesen Wert ändern, wird die Schrittweite auf den Standardwert zurückgesetzt, so dass es notwendig sein kann, anschließend eine neue Schrittweite festzulegen.

increment (engl. für Zunahme)

Gleitkomma +
Legt die angewandte Schrittweite pro Mausklick fest. +
Erlaubte Werte sind 0,001 bis 99999,0 und -1. +
Standardwert ist -1, was zu 100 Schritten von min bis max führt.

inc_speed

Ganzzahlig +
Legt die Zeitverzögerung für die Erhöhung der Geschwindigkeit fest, bei der die Tasten gedrückt gehalten werden. +
Erlaubte Werte sind 20 bis 300. +
Voreinstellung ist 100.

unit (engl. für Einheit)

Zeichenfolge
Legt die Einheit fest, die in der Leiste hinter dem Wert angezeigt wird.
Jede Zeichenkette ist erlaubt.
Standard ist "".

color (engl. für Farbe)

Farbe +
Legt die Farbe des Balkens fest. +
Jede Hex-Farbe ist erlaubt. +
Standard ist "#FF8116".

template (engl. für Vorlage)

Zeichenfolge +
Textvorlage zur Anzeige des Wertes. Es wird die Python-Formatierung verwendet. +
Jedes zulässige Format. +
Standard ist "%.1f".

do_hide_button

Boolescher Wert +
Ob die Schaltfläche zum Erhöhen und Verringern angezeigt oder ausgeblendet werden soll. +
True oder False. +
Voreinstellung = False.

6.10.3. Direkte Programmsteuerung

Es gibt mehrere Möglichkeiten, das Widget direkt mit Python zu steuern.

Verwenden Sie GObject, um die oben aufgeführten Eigenschaften einzustellen:

[widget name].set_property("do_hide_button",bool(value))
[widget name].set_property("color","#FF00FF")
[widget name].set_property("unit", "mm/min")
usw.

Es gibt auch Python-Methoden zur Änderung des Widgets:

[widget name].set_adjustment(gtk-adjustment)

Sie können dem Regler eine bestehende Einstellung zuweisen, so dass es einfach ist, bestehende Schieberegler ohne viele Codeänderungen zu ersetzen. Beachten Sie, dass Sie nach dem Ändern der Einstellung möglicherweise eine neue Schrittweite einstellen müssen, da sie auf die Standardeinstellung zurückgesetzt wird (100 Schritte von MIN bis MAX):

  • [Widgetname].get_value() +
    Gibt den Zählwert als Float zurück

  • [Widgetname].set_value(float(Wert)) +
    Setzt das Widget auf den befohlenen Wert

  • [Widgetname].set_digits(int(Wert)) +
    Setzt die Ziffern des zu verwendenden Wertes

  • [Widgetname].hide_button(bool(Wert)) +
    Die Schaltfläche ausblenden oder anzeigen

images/SpeedControl.png
Abbildung 8. Beispiel Speedcontrol

6.11. Label

hal_label ist ein einfaches Widget, das auf GtkLabel basiert und einen HAL-Pin-Wert in einem benutzerdefinierten Format darstellt.

label_pin_type

Der HAL-Typ des Pins (0:s32, 1:float, 2:u32), siehe auch den Tooltip auf General→HAL pin type (Hinweis: Dies unterscheidet sich von PyVCP, das drei Label-Widgets hat, eines für jeden Typ).

text_template

Bestimmt den angezeigten Text - eine Python-Formatzeichenfolge zur Umwandlung des Pin-Werts in Text. Der Standardwert ist %s (Werte werden mit der Funktion str() umgewandelt), kann aber als Argument für Pythons format()-Methode jede beliebige Zahl enthalten. +
Beispiel: Distance: %.03f zeigt den Text und den Pin-Wert mit 3 Nachkommastellen, aufgefüllt mit Nullen für einen FLOAT-Pin.

6.12. Containers (engl. für Behälter)

  • HAL_HideTable

  • HAL_Table

  • State_Sensitive_Table

  • HAL_HBox (veraltet)

Diese Container sollen dazu dienen, ihre Kinder zu insensibilisieren (auszugrauen) oder zu verstecken. +
Nicht sensibilisierte Kinder reagieren nicht auf Eingaben.

HAL_HideTable

Hat einen HAL BIT-Eingangspin, der steuert, ob dessen untergeordneten Widgets versteckt sind oder nicht.

Pin:
<Panel_basename>. <widgetname>

in Bit-Pin
Wenn der Pin niedrig ist, sind die untergeordneten Widgets sichtbar, was der Standardzustand ist.

HAL_Table und HAL_Hbox

Haben Sie einen HAL BIT-Eingangspin, der steuert, ob ihre untergeordneten Widgets empfindlich sind oder nicht.

Pin:
<Panel_basename>. <widgetname>

in Bit-Pin
Wenn der Pin niedrig ist, sind die untergeordneten Widgets inaktiv, was der Standardzustand ist.

State_Sensitive_Table

Responds to the state to LinuxCNC’s interpreter.
Optionally selectable to respond to must-be-all-homed, must-be-on and must-be-idle.
You can combine them. It will always be insensitive at Estop.
(Has no pin).

Warnung
HAL_Hbox is deprecated - use HAL_Table.
If current panels use it, it won’t fail. You just won’t find it in the GLADE editor anymore.
Future versions of GladeVCP may remove this widget completely and then you will need to update the panel.
Tipp

Wenn Sie feststellen, dass ein Teil Ihrer GladeVCP-Anwendung "ausgegraut" (unempfindlich) ist, prüfen Sie, ob ein HAL_Table-Pin nicht gesetzt oder nicht angeschlossen ist.

6.13. LED

Die hal_led simuliert eine echte Anzeige-LED.
Sie hat einen einzigen BIT-Eingangspin, der ihren Zustand steuert: EIN oder AUS.

6.13.1. Eigenschaften

LEDs haben verschiedene Eigenschaften, die ihr Aussehen und ihre Wirkung bestimmen:

on_color

String, der die ON-Farbe der LED definiert. +
Kann jeder gültige gdk.Color-Name sein. +
Funktioniert nicht unter Ubuntu 8.04.

off_color

String, der die OFF-Farbe der LED definiert. +
Kann jeder gültige gdk.Color-Name oder der spezielle Wert dark sein. dark bedeutet, dass die OFF-Farbe auf den Wert 0,4 der ON-Farbe gesetzt wird.
Funktioniert nicht unter Ubuntu 8.04.

pick_color_on, pick_color_off

Farben für den EIN- und AUS-Zustand.
Diese können als "#RRRRGGGGBBBB"-Strings dargestellt werden und sind optionale Eigenschaften, die Vorrang vor "on_color" und "off_color" haben.

led_size

LED-Radius (für Quadrat - halbe LED-Seite)

led_shape

LED-Form. +
Gültige Werte sind 0 für runde, 1 für ovale und 2 für quadratische Formen.

led_blink_rate

Wenn gesetzt und die LED eingeschaltet ist, blinkt sie.
Die Blinkperiode ist gleich der "led_blink_rate", die in Millisekunden angegeben wird.

create_hal_pin

Aktivierung/Deaktivierung der Erstellung eines HAL-Pins zur Steuerung der LED. +
Wenn kein HAL-Pin erstellt wurde, kann die LED mit einer Python-Funktion gesteuert werden.

6.13.2. Signale

Als Input-Widget unterstützt die LED auch das Signal hal-pin-changed. Wenn Sie in Ihrem Code eine Benachrichtigung erhalten möchten, wenn der HAL-Pin der LED geändert wurde, dann verbinden Sie dieses Signal mit einem Handler, z.B. on_led_pin_changed, und stellen Sie den Handler wie folgt bereit:

def on_led_pin_changed(self,hal_led,data=None):
    print("on_led_pin_changed() - HAL Pin Wert:",hal_led.hal_pin.get())

Dieser wird bei jeder Flanke des Signals und auch beim Programmstart aufgerufen, um den aktuellen Wert zu melden.

images/leds.png
Abbildung 9. Beispiel LEDs

6.14. ProgressBar (engl. für Fortschrittsbalken)

Anmerkung

Dieses Widget wird möglicherweise entfernt.
Verwenden Sie stattdessen die Widgets HAL_HBar und HAL_VBar.

6.14.1. Pins

Der HAL_ProgressBar ist von gtk.ProgressBar abgeleitet und hat zwei Float-HAL-Eingangspins:

<widgetname>

den aktuell anzuzeigenden Wert

<widgetname>-scale

der maximale absolute Wert der Eingabe

6.14.2. Eigenschaften

HAL_ProgressBar hat die folgenden Eigenschaften:

scale

Werteskala. +
Legt den maximalen absoluten Wert der Eingabe fest. Entspricht dem Setzen des <widgetname>.scale-Pins.
Ein Float, Bereich von -224 bis +224.

green_limit

Untere Grenze der grünen Zone

yellow_limit

Untere Grenze der gelben Zone

red_limit

Untergrenze der roten Zone

text_template

Textvorlage zur Anzeige des aktuellen Wertes des __<widgetname>__ Pin.
Python-Formatierung kann für dict {"value":value} verwendet werden.

images/progressbar2.png
Abbildung 10. Beispiel HAL_ProgressBar

6.15. ComboBox

Die HAL_ComboBox ist von der gtk.ComboBox abgeleitet. Sie ermöglicht die Auswahl eines Wertes aus einer Dropdown-Liste.

6.15.1. Pins

Die HAL_ComboBox exportiert zwei HAL-Pins:

<widgetname>-f

Aktueller Wert, Typ FLOAT

<widgetname>-s

Aktueller Wert, Typ s32

6.15.2. Eigenschaften

HAL_ComboBox hat die folgende Eigenschaft, die in Glade gesetzt werden kann:

column

Der Spaltenindex. +
Typ s32. +
Gültiger Bereich von -1..100. +
Standardwert ist -1.

Im Standardmodus setzt dieses Widget die Pins auf den Index des gewählten Listeneintrags. Wenn Ihr Widget also drei Etiketten hat, kann es nur die Werte 0, 1 und 2 annehmen.

Im Spaltenmodus (engl. column Mode) (Spalte > -1) wird der gemeldete Wert aus dem ListStore-Array, wie in Glade definiert, ausgewählt. Typischerweise würde Ihre Widget-Definition also zwei Spalten im ListStore haben, eine mit Text, der im Dropdown angezeigt wird, und einen int- oder float-Wert, der für diese Auswahl verwendet wird.

Es gibt ein Beispiel in configs/apps/by-widget/combobox. {py,ui}, das den Spaltenmodus verwendet, um einen Gleitkommawert aus dem ListStore auszuwählen.

Wenn Sie so verwirrt sind wie ich, wie man ComboBox ListStores und CellRenderer bearbeitet, lesen Sie https://youtu.be/watch?v=Z5_F-rW2cL8.

6.16. Bars (engl. für Balken)

HAL_Bar- und HAL_VBar-Widgets für horizontale und vertikale Balken, die Gleitkommawerte darstellen.

6.16.1. Pins

HAL_Bar und HAL_VBar haben jeweils einen Eingangs-FLOAT-HAL-Pin.

6.16.2. Eigenschaften

Die beiden Balken HAL_Bar und HAL_VBar haben die folgenden Eigenschaften:

invert

Vertauschen Sie die Richtung von Minimum und Maximum. +
Eine invertierte HBar wächst von rechts nach links, eine invertierte VStabi von oben nach unten.

min, max

Mindest- und Höchstwert des gewünschten Bereichs. Es wird Fehler ausgelöst, wenn der aktuelle Wert außerhalb dieses Bereichs liegt.

show limits (engl. für Grenzen zeigen)

Dient zum Auswählen/Abwählen des Grenzwerttextes auf der Leiste.

zero (Null)

Nullpunkt des Bereichs.
Wenn er innerhalb des Min/Max-Bereichs liegt, wächst der Balken von diesem Wert aus und nicht von der linken (oder rechten) Seite des Widgets.
Nützlich zur Darstellung von Werten, die sowohl positiv als auch negativ sein können.

force_width, force_height

Erzwungene Breite oder Höhe des Widgets. +
Wenn nicht festgelegt, wird die Größe aus der Verpackung oder aus der festen Widgetgröße abgeleitet und die Leiste füllt den gesamten Bereich aus.

text_template

Legt wie bei Label das Textformat für Min/Max/Aktuelle Werte fest. +
Kann verwendet werden, um die Anzeige der Werte auszuschalten.

Wert

Setzt die Balkenanzeige auf den eingegebenen Wert. +
Wird nur zum Testen im GLADE-Editor verwendet. +
Der Wert wird von einem HAL-Pin gesetzt.

target value (engl. für Zielwert)

Setzt die Zielzeile auf den eingegebenen Wert. +
Wird nur zum Testen im GLADE-Editor verwendet. +
Der Wert kann in einer Python-Funktion festgelegt werden.

target_width

Breite der Linie, die den Zielwert markiert.

bg_color

Hintergrund (inaktiv) Farbe des Balken (engl. bar).

target_color

Farbe der Ziellinie.

z0_color, z1_color, z2_color

Farben der verschiedenen Wertzonen. +
Standardwerte sind grün, gelb und rot. +
Für eine Beschreibung der Zonen siehe Eigenschaften von z*_border.

z0_border, z1_border

Definieren Sie die Grenzen der Farbzonen. +
Standardmäßig ist nur eine Zone aktiviert. Wenn Sie mehr als eine Zone wünschen, setzen Sie z0_border und z1_border auf die gewünschten Werte, so dass Zone 0 von 0 bis zur ersten Grenze, Zone 1 von der ersten bis zur zweiten Grenze und Zone 2 von der letzten Grenze bis 1 gefüllt wird. +
Die Ränder werden als Brüche festgelegt. +
Gültige Werte reichen von 0 bis 1.

images/hal_hbar.png
Abbildung 11. Horizontaler Balken
images/vscale.png
Abbildung 12. Vertikaler Balken

6.17. Meter

HAL_Meter ist ein Widget ähnlich dem PyVCP-Meter - es stellt einen Gleitkommawert dar.

6.17.1. Pins

HAL_Meter hat einen Eingangs-FLOAT-HAL-Pin.

6.17.2. Eigenschaften

HAL Meter hat die folgenden Eigenschaften:

min, max

Mindest- und Höchstwert des gewünschten Bereichs.
Es handelt sich nicht um eine Fehlerbedingung, wenn der aktuelle Wert außerhalb dieses Bereichs liegt.

force_size

Erzwungener Durchmesser des Widgets.
Wenn nicht festgelegt, wird die Größe aus der Packung oder aus der festen Widgetgröße abgeleitet, und der Zähler füllt den gesamten verfügbaren Platz unter Berücksichtigung des Seitenverhältnisses.

text_template

Legt, wie bei Label, das Textformat für den aktuellen Wert fest.
Kann verwendet werden, um die Anzeige des Wertes auszuschalten.

label

Großes Etikett über der Metermitte.

Sublabel

Kleines Etikett unter der Mitte des Messgeräts.

bg_color

Hintergrundfarbe des Messgeräts.

z0_color, z1_color, z2_color

Farben der verschiedenen Wertzonen. +
Standardwerte sind grün, gelb und rot. +
Für eine Beschreibung der Zonen siehe Eigenschaften von z*_border.

z0_border, z1_border

Definieren Sie die Grenzen der Farbzonen. +
Standardmäßig ist nur eine Zone aktiviert. Wenn Sie mehr als eine Zone wünschen, setzen Sie z0_border und z1_border auf die gewünschten Werte, so dass Zone 0 vom Minimum bis zum ersten Rand, Zone 1 vom ersten bis zum zweiten Rand und Zone 2 vom letzten Rand bis zum Maximum gefüllt wird. +
Die Ränder werden als Werte im Bereich min-max eingestellt.

images/hal_meter.png
Abbildung 13. Beispiel HAL-Messgeräte

6.18. HAL_Graph

Dieses Widget dient zum Auftragen von Werten über die Zeit.

6.19. Gremlin-Werkzeugpfad-Vorschau für NGC-Dateien

Gremlin ist ein Plot-Vorschau-Widget ähnlich dem AXIS-Vorschaufenster. Es setzt eine laufende LinuxCNC-Umgebung wie AXIS oder Touchy voraus. Um sich damit zu verbinden, prüft die INI_FILE_NAME Umgebungsvariable. Gremlin zeigt die aktuelle NGC-Datei an - er überwacht auf Änderungen und lädt die NGC-Datei neu, wenn sich der Dateiname in AXIS/Touchy ändert. Wenn Sie es in einer GladeVCP-Anwendung ausführen, wenn LinuxCNC nicht läuft, könnten Sie einen Traceback bekommen, weil das Gremlin-Widget den LinuxCNC-Status, wie den aktuellen Dateinamen, nicht finden kann.

6.19.1. Pins

Gremlin exportiert keine HAL-Pins.

6.19.2. Eigenschaften

Gremlin hat die folgenden Eigenschaften:

enable_dro

Zeigt den Tropfen auf der Grafik an.
Standard = true.

show_velocity

Dies zeigt die Werkzeuggeschwindigkeit an.
Vorteinstellung = true.

use_commanded

Dies wählt die zu verwendende DRO aus: befohlene oder tatsächliche Werte.
Voreinstellung = true.

metric_units

Dies legt fest was die DRO nutzt: metrische oder imperiale Einheiten.
Voreinstellung = true.

show_rapids

Dies legt fest, dass der Plotter die schnelle Bewegungen zeigt.
Voreinstellung = true.

show_dtg_

Hiermit wird die Anzeige des Restweges auf der DRO ausgewählt.
Voreinstellung = true.

use_relative (relativ anzeigen)

Hiermit wird festgelegt, dass die Anzeige der Werte relativ zu den Koordinaten des Benutzersystems oder der Maschine erfolgen soll.
Voreinstellung = true.

show_live_plot (Live-Plot anzeigen)

Hiermit wird dem Plotter mitgeteilt, ob er zeichnen soll oder nicht.
Voreinstellung = true.

show_limits (engl. für Grenzen zeigen)

Hiermit wird der Plotter angewiesen, die Grenzen der Maschine anzuzeigen.
Voreinstellung = true.

show_lathe_radius (engl. für Drehmaschinenradius anzeigen)

Hiermit wird die DRO Anzeige der X-Achse in Radius oder Durchmesser gewählt, wenn der Drehmaschinenmodus aktiviert ist (wählbar in der INI-Datei mit LATHE = 1).
Voreinstellung = true.

show_extents_option (Ausmaße anzeigen)

Hiermit wird der Plotter angewiesen, die Außenmaße der Maschine anzuzeigen.
Voreinstellung = true.

show_tool (Werkzeug anzeigen)

Hiermit wird der Plotter angewiesen, das Werkzeug zu zeichnen.
Voreinstellung = true.

show_program (Programm zeigen)

Zeigt das G-Code-Programm an.
Standard = True

use_joints_mode

Wird in nicht trivialkins Maschinen (z.B. Robotern) verwendet.
Standard = false.

grid_size

Legt die Größe des Gitters fest (nur in den Ansichten X, Y und Z sichtbar). +
Standardwert ist 0

use_default_controls

Damit wird die Standard-Maussteuerung deaktiviert. +
Dies ist besonders nützlich, wenn Sie einen Touchscreen verwenden, da die Standardsteuerungen nicht gut funktionieren. Sie können programmatisch Steuerelemente mit Python und der Handler-Datei-Technik hinzufügen. +
Standard = true.

view (engl. für Sicht)

Kann einer der Werte x, y, y2 , z, z2 , p (Perspektive) sein.
Standardmäßig wird die Ansicht z verwendet.

enable_dro

Typ = boolesch. +
Ob ein DRO auf dem Plot gezeichnet werden soll oder nicht. +
Voreinstellung = true.

mouse_btn_mode

Typ = Ganzzahl.
Maustastenbehandlung: führt zu verschiedenen Funktionen der Taste:

  • 0 = default: left rotate, middle move, right zoom

  • 1 = left zoom, middle move, right rotate

  • 2 = left move, middle rotate, right zoom

  • 3 = left zoom, middle rotate, right move

  • 4 = left move, middle zoom, right rotate

  • 5 = left rotate, middle zoom, right move

  • 6 = left move, middle zoom, right zoom

Modus 6 wird für Plasmas und Drehbänke empfohlen, da für diese Maschinen keine Rotation erforderlich ist.

6.19.3. Direkte Programmsteuerung

Es gibt mehrere Möglichkeiten, das Widget direkt mit Python zu steuern.

Verwenden Sie GObject, um die oben aufgeführten Eigenschaften einzustellen:

[widget name].set_property('view','P')
[widget name].set_property('metric_units',False)
[widget name].set_property('use_default_controls',False)
[widget name].set_property('enable_dro' False)
[widget name].set_property('show_program', False)
[widget name].set_property('show_limits', False)
[widget name].set_property('show_extents_option', False)
[widget name].set_property('show_live_plot', False)
[widget name].set_property('show_tool', False)
[widget name].set_property('show_lathe_radius',True)
[widget name].set_property('show_dtg',True)
[widget name].set_property('show_velocity',False)
[widget name].set_property('mouse_btn_mode', 4)

Es gibt Python-Methoden:

[widget name].show_offsets = True
[widget name].grid_size = .75
[widget name].select_fire(event.x,event.y)
[widget name].select_prime(event.x,event.y)
[widget name].start_continuous_zoom(event.y)
[widget name].set_mouse_start(0,0)
[widget name].gremlin.zoom_in()
[widget name].gremlin.zoom_out()
[widget name].get_zoom_distance()
[widget name].set_zoom_distance(dist)
[widget name].clear_live_plotter()
[widget name].rotate_view(x,y)
[widget name].pan(x,y)
Hinweise
  • Wenn Sie alle Plot-Optionen auf false, show_offsets aber auf true setzen, erhalten Sie eine Seite mit Offsets anstelle einer grafischen Darstellung.

  • Es ist viel benutzerfreundlicher, wenn Sie die Zoomdistanz ermitteln, bevor Sie die Ansicht ändern, und dann die Zoomdistanz zurücksetzen.

  • wenn Sie ein Element in der Vorschau auswählen, wird das ausgewählte Element als Rotationsmittelpunkt verwendet

images/gremlin.png
Abbildung 14. Gremlin Beispiel

6.20. HAL_Offset

Das HAL_Offset-Widget wird verwendet, um den Offset einer einzelnen Achse anzuzeigen.

6.20.1. Eigenschaften

HAL_Offset hat die folgenden Eigenschaften:

display_units_mm

Anzeige in metrischen Einheiten.

joint_number

Dient zur Auswahl, welche Achse (technisch gesehen welche Gelenk) angezeigt wird.
Auf einer Trivialkins-Maschine (Fräse, Drehmaschine, Oberfräse) sind Achse und Gelenknummer gleich:

0:X 1:Y 2:Z 3:A 4:B 5:C 6:U 7:V 8:W
mm_text_template

Sie können die Python-Formatierung verwenden, um die Position mit unterschiedlicher Genauigkeit anzuzeigen.

imperial_text_template

Sie können die Python-Formatierung verwenden, um die Position mit unterschiedlicher Genauigkeit anzuzeigen.

reference_type
0:G5x 1:Werkzeug 2:G92 3:Drehung um Z

6.21. DRO-Widget

Das DRO-Widget wird verwendet, um die aktuelle Achsenposition anzuzeigen.

6.21.1. Eigenschaften

Es hat die folgenden Eigenschaften:

display_units_mm

Dient zum Umschalten der Anzeigeeinheiten zwischen metrisch und imperial. Standard ist False.

actual (engl. für tatsächlich)

Wählen Sie die tatsächliche Position (Rückmeldung, engl. feedback) oder die Sollposition aus. Der Standardwert ist True.

Durchmesser

Durchmesser für eine Drehmaschine anzeigen. Standard ist False.

mm_text_template

Sie können die Python-Formatierung verwenden, um die Position mit unterschiedlicher Genauigkeit anzuzeigen. Standard ist "%10.3f".

imperial_text_template

Sie können die Python-Formatierung verwenden, um die Position mit unterschiedlicher Genauigkeit anzuzeigen. Standard ist "%9.4f".

joint_number

Dient zur Auswahl, welche Achse (technisch gesehen welches Gelenk) angezeigt wird. Standard ist 0.
Auf einer Trivialkins-Maschine (Fräsmaschine, Drehmaschine, Oberfräse) sind die Achsen im Vergleich zur Gelenknummer:

0:X 1:Y 2:Z 3:A 4:B 5:C 6:U 7:V 8:W +
reference_type
  • 0 = absolute (Maschinen-Ursprung).

  • 1 = relative (zum aktuellen Ursprung der Benutzerkoordinate - G5x).

  • 2 = distance-to-go (engl. für verbleibender Weg) (relativ zum aktuellen Ursprung der Benutzerkoordinate). Standardeinstellung ist 0.

font_family

Geben Sie die Schriftfamilie an, z. B. mono. Standardmäßig ist sans eingestellt. Wenn die Schriftart nicht vorhanden ist, wird die aktuelle Systemschriftart verwendet. Standardwert ist sans.

font_size

Geben Sie die Größe der Schrift zwischen 8 und 96 an. Standard ist 26.

font_weight

Geben Sie die Stärke der Schrift an. Wählen Sie zwischen ligher (engl. für heller), normal, bold (engl. für fett) und bolder (engl. für fetter). Standard ist bold (engl. für fett).

unhomed_color

Die Farbe des Textes, wenn er nicht beherbergt ist, wird als Gdk.RGBA-Farbe angegeben. Standard ist rot, Gdk.RGBA(red=1.000000, green=0.000000, blue=0.000000, alpha=1.000000), jeweils englisch für rot, grün und blau

homed_color

Die Farbe des Textes, wenn Maschine nicht am Referenzpunkt, wird als Gdk.RGBA-Farbe angegeben. Standard ist rot, Gdk.RGBA(red=0.000000, green=0.501961, blue=0.000000, alpha=1.000000), jeweils englisch für rot, grün und blau

Hinweise
  • Wenn die Anzeige rechtsbündig sein soll, stellen Sie die horizontale Ausrichtung auf End (engl. für Ende).

  • Der Hintergrund des Widgets ist eigentlich durchsichtig - wenn Sie es also über einem Bild platzieren, werden die DRO-Zahlen oben ohne Hintergrund angezeigt. Es gibt eine spezielle Technik, um dies zu erreichen. Siehe die animierten Funktionsdiagramme unten.

  • Das DRO Widget ist ein modifiziertes gtk Label Widget. Als solches kann dem DRO Widget viel von dem getan werden, was mit einem gtk-Label gemacht werden kann.

  • Die Schrifteigenschaften können auch über ein CSS-Stylesheet festgelegt werden, das die höchste Priorität hat und die durch GObject-Eigenschaften festgelegten Werte außer Kraft setzt.

6.21.2. Direkte Programmsteuerung

Es gibt mehrere Möglichkeiten, das Widget direkt mit Python zu steuern.

Verwendung von GObject zur Einstellung der oben aufgeführten Eigenschaften
[widget name].set_property("display_units_mm", True)
[widget name].set_property("actual", True)
[widget name].set_property("diameter", True)
[widget name].set_property("mm_text_template", "%10.3f")
[widget name].set_property("imperial_text_template", "%9.4f")
[widget name].set_property("joint_number", 3)
[widget name].set_property("reference_type", 3)
[widget name].set_property("font_family", "mono")
[widget name].set_property("font_size", 30)
[widget name].set_property("font_weight", "bold")
# es ist einfacher, Farben durch den Aufruf einer Funktion zu lesen:
def str_to_rgba(color):
  c = Gdk.RGBA()
  c.parse(color)
  return c

[widget name].set_property("unhomed_color", str_to_rgba("magenta"))
[widget name].set_property("homed_color", str_to_rgba("cyan"))
Verwendung eines CSS-Stylesheets zum Festlegen von Schrifteigenschaften

Farben können in einem von mehreren Formaten angegeben werden, die alle dieselbe Farbe angeben, nämlich Rot, *#ff0000, *rgb(255,0,0) oder rgba(255,0,0,255).

Die Farben können entweder gemeinsam referenziert werden:

.dro_unhomed {color: magenta}
.dro_homed {color: cyan}

oder einzeln nach Widget-Namen:

#[widget name].dro_unhomed {color: magenta}
#[widget name].dro_homed {color: cyan}

Die anderen Stileigenschaften müssen über den Widgetnamen referenziert werden:

#[widget name], #[widget name], #[widget name] {
    font-family: mono;
    font-size: 60px;
    font-weight: lighter;
}
Es gibt zwei Python-Methoden
[widget name].set_dro_inch()
[widget name].set_dro_metric()

6.22. Combi_DRO Widget

Das Combi_DRO-Widget wird verwendet, um die aktuelle, die relative Achsenposition und die zu fahrende Strecke in einem DRO anzuzeigen.
Durch Klicken auf das DRO wird die Reihenfolge der DRO umgeschaltet.
Im relativen Modus wird das aktuelle Koordinatensystem angezeigt.

6.22.1. Eigenschaften

Combi_DRO hat die folgenden Eigenschaften:

joint_number

Dient zur Auswahl, welche Achse (technisch gesehen welche Gelenk) angezeigt wird.
Auf einer Trivialkins-Maschine (Fräse, Drehmaschine, Oberfräse) sind Achse und Gelenknummer gleich:

0:X 1:Y 2:Z usw.
actual (engl. für tatsächlich)

Wählen Sie die tatsächliche (Rückmeldung) oder die befohlene Position.

metric_units

Dient zum Umschalten der Anzeigeeinheiten zwischen metrisch und imperial.

auto_units

Die Einheiten werden zwischen metrisch und imperial umgeschaltet, je nachdem, ob der aktive G-Code G20 oder G21 ist. +
Voreinstellung ist TRUE.

Durchmesser

Ob die Position als Durchmesser oder Radius angezeigt werden soll. +
Im Durchmessermodus zeigt die Positionsanzeige den Gelenkwert multipliziert mit 2 an.

mm_text_template

Sie können die Python-Formatierung verwenden, um die Position mit unterschiedlicher Genauigkeit anzuzeigen.
Standard ist "%10.3f".

imperial_text_template

Sie können die Python-Formatierung verwenden, um die Position mit unterschiedlicher Genauigkeit anzuzeigen.
Standard ist "%9.4f".

homed_color

Die Vordergrundfarbe der DRO-Nummern, wenn das Gelenk referenziert ist.
Standard ist grün.

unhomed_color

Die Vordergrundfarbe der DRO-Nummern, wenn das Gelenk nicht referenziert ist.
Standard ist rot.

abs_color

Die Hintergrundfarbe der DRO, wenn die Haupt-DRO absolute Koordinaten anzeigt.
Standard ist blau.

rel_color

Die Hintergrundfarbe des DRO, wenn das Haupt-DRO relative Koordinaten anzeigt.
Standard ist schwarz.

dtg_color

Die Hintergrundfarbe der DRO, wenn die Haupt-DRO die verbleibende Entfernung anzeigt.
Standard ist gelb.

font_size

Die Schriftgröße der großen Zahlen, die kleinen Zahlen werden 2,5 mal kleiner sein.
Der Wert muss eine ganze Zahl im Bereich von 8 bis 96 sein.
Standardwert ist 25.

toggle_readout

Ein linker Mausklick schaltet die DRO-Anzeige zwischen den verschiedenen Modi um ["Rel", "Abs", "DTG"].
Durch Deaktivieren des Kontrollkästchens können Sie dieses Verhalten abschalten. Das Umschalten kann immer noch mit [Widgetname].toggle_readout() durchgeführt werden.
Der Wert muss boolesch sein.
Voreinstellung ist TRUE.

cycle_time

Die Zeit, die ein DRO zwischen zwei Abfragen wartet.
Diese Einstellung sollte nur geändert werden, wenn Sie mehr als 5 DROs gleichzeitig verwenden, z.B. bei einer 6-Achsen-Konfiguration, um zu vermeiden, dass die DRO die Hauptanwendung zu sehr verlangsamt.
Der Wert muss eine ganze Zahl im Bereich von 100 bis 1000 sein. FIXME unit=ms ?
Voreinstellung ist 150.

6.22.2. Direkte Programmsteuerung

Verwenden Sie GObject, um die oben aufgeführten Eigenschaften einzustellen:

[widget name].set_property(property, value)

Es gibt mehrere Python-Methoden zur Steuerung des Widgets:

  • [Widgetname].set_to_inch(state)
    Legt fest, dass die DRO imperiale Einheiten anzeigt.
    state = boolesch (True oder False)
    Voreinstellung ist FIXME.

  • [Widgetname].set_auto_units(state)
    Wenn True, ändert die DRO die Einheiten entsprechend dem aktiven G-Code (G20 / G21).
    state = boolean (Wahr oder Falsch)
    Standard ist True.

  • [Name des Widgets].set_to_diameter(state)
    Wenn True, zeigt die DRO den Durchmesser und nicht den Radius an, d. h. den Achsenwert multipliziert mit 2 (speziell für Drehmaschinen erforderlich).
    state = boolean (Wahr oder Falsch)
    Der Standardwert ist Falsch.

  • [Widgetname].toggle_readout()
    Schaltet die Reihenfolge des DRO im Widget um.

  • [Widget-Name].change_axisletter(Buchstabe)
    Ändert den automatisch angegebenen Achsenbuchstaben.
    Sehr nützlich, um eine Drehmaschine DRO von X auf R oder D zu ändern.
    letter = Zeichenfolge

  • [Widgetname].get_order()
    Gibt die Reihenfolge der DRO im Widget zurück, die hauptsächlich dazu dient, sie konsistent zu halten.
    Die Reihenfolge wird auch mit dem Klicksignal übertragen.
    Gibt eine Liste mit der Reihenfolge zurück.

  • [Name des Widgets].set_order(order)
    Legt die Reihenfolge der DRO fest, die hauptsächlich verwendet wird, um sie konsistent zu halten.
    order = Listenobjekt, muss eines der folgenden sein:

    • ["Rel", "Abs", "DTG"] (Standard)

    • ["DTG", "Rel", "Abs"]

    • ["Abs", "DTG", "Rel"]

  • [Widgetname].get_position()
    Liefert die Position des DRO als eine Liste von Floats.
    Die Reihenfolge ist unabhängig von der auf dem DRO angezeigten Reihenfolge und wird als [Absolut , relativ , DTG] angegeben.

    • Absolut = die Maschinenkoordinaten, abhängig von der tatsächlichen Eigenschaft, die eine tatsächliche oder befohlene Position ergibt.

    • Relativ = sind die Koordinaten des aktuellen Koordinatensystems.

    • DTG = die zu gehende Strecke.
      Wird meistens 0 sein, da diese Funktion aufgrund von Zeitverzögerungen nicht verwendet werden sollte, während sich die Maschine bewegt.

Das Widget sendet die folgenden Signale aus:

  • clicked
    Dieses Signal wird ausgesendet, wenn der Benutzer auf das Combi_DRO-Widget geklickt hat.
    Es wird die folgenden Daten senden:

    • widget = Widget-Objekt
      Das Widget-Objekt, welches das Signal sendet.

    • joint_number = ganze Zahl
      Die gemeinsame Nummer des DRO, wobei 0:X 1:Y 2:Z etc.

    • order = Listenobjekt +
      Die Reihenfolge des DRO in diesem Widget. +
      Die Reihenfolge kann verwendet werden, um andere Combi_DRO-Widgets mit [widget name].set_order(order) auf die gleiche Reihenfolge zu setzen.

  • units_changed +
    Dieses Signal wird ausgegeben, wenn die DRO-Einheiten gewechselt werden. +
    Es sendet die folgenden Daten:

    • widget = Widget-Objekt
      Das Widget-Objekt, welches das Signal sendet.

    • metric_units = boolesch +
      True, wenn die DRO metrische Einheiten anzeigt, False, wenn die Anzeige imperial ist.

  • system_changed+
    Dieses Signal wird ausgegeben, wenn die DRO-Einheiten gewechselt werden. +
    Es sendet die folgenden Daten:

    • widget = Widget-Objekt
      Das Widget-Objekt, welches das Signal sendet.

    • system = Zeichenfolge +
      Das eigentliche Koordinatensystem. Wird einer von G54 G55 G56 G57 G58 G59 G59.1 G59.2 G59.3 oder Rel sein, wenn überhaupt nicht ausgewählt wurde, was nur in Glade passieren wird, wenn kein LinuxCNC läuft.

Es gibt einige Informationen, die Sie über Befehle erhalten können und die für Sie von Interesse sein könnten:

  • [Widgetname].system
    Das eigentliche System, wie im Signal system_changed erwähnt.

  • [Widget-Name].homed +
    True, wenn das Gelenk referenziert ist.

  • [Widgetname].machine_units +
    0 wenn imperial, 1 wenn metrisch.

images/combi_dro.png
Abbildung 15. Beispiel: Drei Combi_DRO in einem Fenster
X = Relativer Modus +
Y = Absoluter Modus +
Z = DTG-Modus

6.23. IconView (Dateiauswahl)

Dies ist ein Touchscreen-freundliches Widget zur Auswahl einer Datei und zum Wechseln von Verzeichnissen.

6.23.1. Eigenschaften

Das IconView-Widget hat die folgenden Eigenschaften:

icon_size

Legt die Größe des angezeigten Symbols fest. +
Erlaubte Werte sind Ganzzahlen im Bereich von 12 bis 96. +
Voreinstellung ist 48.

start_dir

Legt das Verzeichnis fest, in dem das Widget beim ersten Mal angezeigt wird.
Muss ein String sein, der einen gültigen Verzeichnispfad enthält.
Standard ist "/".

jump_to_dir

Legt das Verzeichnis fest, in das gesprungen werden soll und das durch die entsprechende Schaltfläche in der unteren Schaltflächenliste ausgewählt wird (die 5. Schaltfläche von links).
Muss ein String sein, der einen gültigen Verzeichnispfad enthält.
Voreinstellung ist "\~".

filetypes

Legt den Dateifilter für die anzuzeigenden Objekte fest.
Muss eine Zeichenkette sein, die eine durch Komma getrennte Liste von Erweiterungen enthält, die angezeigt werden sollen.
Standard ist "ngc,py".

sortorder

Legt die Sortierreihenfolge des angezeigten Symbols fest. +
Muss ein ganzzahliger Wert von 0 bis 3 sein, mit den entsprechenden Konstanten:

  • 0 = ASCENDING (engl. für aufsteigend) (nach Dateinamen sortiert)

  • 1 = DESCENDING (engl. für absteigend) (Sortierung nach Dateinamen)

  • 2 = FOLDERFIRST (zuerst die Ordner, dann die Dateien anzeigen), Standard

  • 3 = FILEFIRST (zuerst die Dateien, dann die Ordner anzeigen)

6.23.2. Direkte Programmsteuerung

Verwenden Sie GObject, um die oben aufgeführten Eigenschaften einzustellen:

[Widgetname].set_property(Eigenschaft,Wert)

Es gibt Python-Methoden zur Steuerung des Widgets:

  • [Widgetname].show_buttonbox(state) +
    Bei False wird das untere Schaltflächenfeld ausgeblendet. +
    Dies ist hilfreich in benutzerdefinierten Bildschirmen, mit speziellen Schaltflächen-Layouts, um das Layout der GUI nicht zu verändern. Ein gutes Beispiel dafür ist GMOCCAPY. +
    state = boolescher Wert (True oder False). +
    Voreinstellung ist True.

  • [Widgetname].show_filelabel(state)+
    Bei True wird das Dateilabel (zwischen dem IconView-Fenster und dem unteren Schaltflächenfeld) angezeigt. +
    Das Ausblenden dieses Labels kann Platz sparen, aber das Anzeigen ist sehr nützlich für die Fehlersuche. +
    state = boolescher Wert (True oder False). +
    Voreinstellung ist True.

  • [Widgetname].set_icon_size(iconsize) +
    Setzt die Größe des Icons. +
    Muss eine ganze Zahl im Bereich von 12 bis 96 sein. +
    Voreinstellung = 48.

  • [Widgetname].set_directory(Verzeichnis) +
    Ermöglicht das Setzen eines anzuzeigenden Verzeichnisses. +
    Verzeichnis = String (ein gültiger Dateipfad).

  • [Widgetname].set_filetypes(Dateitypen) +
    Legt den zu verwendenden Dateifilter fest. +
    Es werden nur Dateien mit den angegebenen Erweiterungen angezeigt. +
    Dateitypen = String mit einer durch Komma getrennten Liste von Erweiterungen. +
    Voreinstellung = "ngc,py".

  • [Widgetname].get_selected() +
    Gibt den Pfad der ausgewählten Datei zurück, oder None, wenn ein Verzeichnis ausgewählt wurde.

  • [Widgetname].refresh_filelist() +
    Aktualisiert die Dateiliste. +
    Wird benötigt, wenn Sie eine Datei hinzufügen, ohne das Verzeichnis zu ändern.

Wenn der Button ausgeblendet wurde, können Sie die Funktionen dieses Buttons über die angeklickten Signale wie folgt erreichen:

[widget name].btn_home.emit("clicked")
[widget name].btn_jump_to.emit("clicked")
[widget name].btn_sel_prev.emit("clicked")
[widget name].btn_sel_next.emit("clicked")
[widget name].btn_get_selected.emit("clicked")
[widget name].btn_dir_up.emit("clicked")
[widget name].btn_exit.emit("clicked")

6.23.3. Signale

Das Widget sendet die folgenden Signale aus:

  • selected (engl. für ausgewählt) +
    Dieses Signal wird ausgegeben, wenn der Benutzer ein Symbol auswählt. +
    Es gibt einen String zurück, der einen Dateipfad enthält, wenn eine Datei ausgewählt wurde, oder None, wenn ein Verzeichnis ausgewählt wurde.

  • empfindlich +
    Dieses Signal wird ausgegeben, wenn die Schaltflächen ihren Zustand von sensitiv zu nicht sensitiv oder umgekehrt ändern. +
    Dieses Signal ist nützlich, um die umgebende GUI mit der Schaltfläche des Widgets synchronisiert zu halten. Siehe GMOCCAPY als Beispiel. +
    Es gibt den Buttonnamen und den neuen Zustand (engl. state) zurück:

    • Der Name der Schaltfläche ist einer der folgenden: btn_home, btn_dir_up, btn_sel_prev, btn_sel_next, btn_jump_to oder btn_select.

    • state ist ein boolescher Wert und wird True oder False sein.

  • exit +
    Dieses Signal wird ausgegeben, wenn der Exit-Button gedrückt wurde, um die IconView zu schließen. +
    Meistens benötigt, wenn die Anwendung als eigenständige Anwendung gestartet wird.

images/iconview.png
Abbildung 16. Iconview Beispiel

6.24. Rechner-Widget

Dies ist ein einfaches Taschenrechner-Widget, das für numerische Eingaben verwendet werden kann. +
Sie können die Anzeige voreinstellen und das Ergebnis oder den voreingestellten Wert abrufen.

6.24.1. Eigenschaften

Rechner (engl. calculator) hat folgende Eigenschaften:

is_editable

Damit kann die Eingabeanzeige über eine Tastatur eingegeben werden.

font

Hier können Sie die Schriftart für die Anzeige einstellen.

6.24.2. Direkte Programmsteuerung

Es gibt mehrere Möglichkeiten, das Widget direkt mit Python zu steuern.

Verwenden Sie goobject, um die oben aufgeführten Eigenschaften einzustellen:

[widget name].set_property("is_editable",True)
[widget name].set_property("font","sans 25")

Es gibt Python-Methoden:

  • [Widgetname].set_value(2.5)
    Damit ist die Anzeige voreingestellt und wird aufgezeichnet.

  • [Widgetname].set_font("sans 25")

  • [Widgetname].set_editable(True)

  • [Widgetname].get_value()
    Gibt den berechneten Wert zurück - eine Fließkommazahl.

  • [Widgetname].set_editable(True)

  • [Widgetname].get_preset_value()
    Gibt den aufgezeichneten Wert zurück: eine Fließkommazahl.

6.25. Werkzeugeditor-Widget (engl. tooleditor widget)

Dies ist ein "Werkzeug-Editor"-Widget zum Anzeigen und Ändern einer Werkzeugdatei. +
Im Drehmaschinenmodus werden Verschleißkorrekturen und Werkzeugkorrekturen separat angezeigt. +
Verschleißkorrekturen werden durch Werkzeugnummern über 10000 (Fanuc-Stil) gekennzeichnet. +
Es überprüft die aktuelle Datei einmal pro Sekunde, um zu sehen, ob LinuxCNC es aktualisiert.

Anmerkung
LinuxCNC erfordert Mapping von Werkzeug-Aufrufe, um Verschleiß-Offsets anzuwenden.

6.25.1. Eigenschaften

tooleditor hat die folgenden Eigenschaften:

font

Zu verwendende Anzeige-Schriftart

hide_columns

Dadurch werden die angegebenen Spalten ausgeblendet. +
Die Spalten werden (in dieser Reihenfolge) wie folgt bezeichnet: s,t,p,x,y,z,a,b,c,u,v,w,d,i,j,q. +
Sie können eine beliebige Anzahl von Spalten ausblenden, einschließlich der Auswahl und der Kommentare.

lathe_display_type

Format der Drehmaschine anzeigen

6.25.2. Direkte Programmsteuerung

Es gibt mehrere Möglichkeiten, das Widget direkt mit Python zu steuern.

Verwenden Sie goobject, um die oben aufgeführten Eigenschaften einzustellen:

[Widgetname].set_properties('hide_columns','uvwijq')

Dadurch würden die Spalten uvwij und q ausgeblendet und alle anderen angezeigt.

Es gibt Python-Methoden:

  • [Widgetname].set_visible("ijq",False)
    Blendet die Spalten ij und Q aus und belässt den Rest so, wie er war.

  • [Widgetname].set_filename(pfad_zur_datei)
    Setzt und lädt die Werkzeugdatei.

  • [Widgetname].reload(None)
    Lädt die aktuelle Werkzeugdatei neu.

  • [Widgetname].set_font('sans 16,tab='1') +
    Setzt die (Pango)-Schriftart für die Registerkarte, den Spaltentitel und die Werkzeugdaten. +
    Die all_offsets, wear_offsets, tool_offsets können gleichzeitig gesetzt werden, indem man 1, 2 und/oder 3 an den Tab-String anhängt. +
    Standardmäßig sind alle Registerkarten eingestellt.

  • [Widgetname].set_title_font('sans 16,tab='1') +
    Setzt die (Pango)-Schriftart nur für die Spaltentitel. +
    Die all_offsets, wear_offsets, tool_offsets können gleichzeitig gesetzt werden, indem man 1, 2 und/oder 3 an den Tab-String anhängt. +
    Standardmäßig sind alle Tabulatoren gesetzt.

  • [Widgetname].set_tab_font('sans 16,tab='1') +
    Setzt die (Pango)-Schriftart nur auf den Registerkarten. +
    Die all_offsets, wear_offsets, tool_offsets können gleichzeitig gesetzt werden, indem man 1, 2 und/oder 3 an den Tab-String anhängt. +
    Standardmäßig sind alle Tabs gesetzt.

  • [Widgetname].set_col_visible("abcUVW", False, tab='1') +
    Dies würde die abcuvw-Spalten auf der Registerkarte 1 (all_offsets) ausblenden (False)

  • [widget name].set_lathe_display(value) +
    Blendet die Verschleiß- und Werkzeugkorrekturtabellen für Drehbänke ein oder aus

  • [Widgetname].get_toolinfo(toolnum) +
    Gibt das Werkzeuginformationsfeld der angeforderten Werkzeugnummer oder des aktuellen Werkzeugs zurück, wenn keine Werkzeugnummer angegeben ist. +
    Gibt None zurück, wenn das Werkzeug nicht in der Tabelle gefunden wurde oder wenn es kein aktuelles Werkzeug gibt.

  • [Widgetname].hide_buttonbox(self, True) +
    Komfortable Methode zum Ausblenden von Schaltflächen. +
    Sie müssen diese Methode nach show_all() aufrufen.

  • [Widgetname].get_selected_tool() +
    Gibt die vom Benutzer ausgewählte (hervorgehobene) Werkzeugnummer zurück.

  • [Widgetname].set_selected_tool(toolnumber) +
    Wählt das gewünschte Werkzeug aus (markiert es).

images/gtk-tooledit.png
Abbildung 17. Werkzeug-Editor (engl. tooleditor) Beispiel

6.26. Offset-Seite

Das Widget Offsetpage dient der Anzeige/Bearbeitung der Offsets aller Achsen.
Es hat praktische Schaltflächen für die Nullstellung von G92- und Rotation-Around-Z-Offsets.
Sie können den Bearbeitungsmodus nur auswählen, wenn die Maschine eingeschaltet und im Leerlauf ist.
Zu diesem Zeitpunkt können Sie die Offsets in der Tabelle direkt bearbeiten. Heben Sie die Auswahl der Schaltfläche "Bearbeiten" auf, damit die Offset-Seite die Änderungen wiedergeben kann.

6.26.1. Eigenschaften

Es hat die folgenden Eigenschaften:

display_units_mm

Anzeige in metrischen Einheiten

hide_columns

Eine Liste der auszublendenden Spalten ohne Leerzeichen. Die Spalten werden (in dieser Reihenfolge) wie folgt bezeichnet: xyzabcuvwt.
Sie können jede der Spalten ausblenden.

hide_rows

Eine Liste der auszublendenden Zeilen ohne Leerzeichen.
Die Zeilen werden (der Reihe nach) wie folgt bezeichnet: 0123456789abc.
Sie können jede der Zeilen ausblenden.

font

Legt Art und Größe der Schriftart fest.

highlight_color

Beim Bearbeiten ist dies die Hervorhebungsfarbe.

foreground_color

Wenn OffsetPage ein aktives Benutzerkoordinatensystem erkennt, wird diese Farbe für den Text verwendet.

mm_text_template

Sie können die Python-Formatierung verwenden, um die Position mit unterschiedlicher Genauigkeit anzuzeigen.

imperial_text_template

Sie können die Python-Formatierung verwenden, um die Position mit unterschiedlicher Genauigkeit anzuzeigen.

6.26.2. Direkte Programmsteuerung

Es gibt mehrere Möglichkeiten, das Widget direkt mit Python zu steuern.

Verwenden Sie goobject, um die oben aufgeführten Eigenschaften einzustellen:

[widget name].set_property("highlight_color",gdk.Color('blue'))
[widget name].set_property("foreground_color",gdk.Color('black'))
[widget name].set_property("hide_columns","xyzabcuvwt")
[widget name].set_property("hide_rows","123456789abc")
[widget name].set_property("font","sans 25")

Es gibt Python-Methoden zur Steuerung des Widgets:

  • [widget name].set_filename("../../../configs/sim/gscreen/gscreen_custom/sim.var")

  • [widget name].set_col_visible("Yabuvw",False)

  • [widget name].set_row_visible("456789abc",False)

  • [widget name].set_to_mm()

  • [widget name].set_to_inch()

  • [widget name].hide_button_box(True)

  • [widget name].set_font("sans 20")

  • [widget name].set_highlight_color("violet")

  • [widget name].set_foreground_color("yellow")

  • [Widgetname].mark_active("G55")
    Ermöglicht es Ihnen, eine Zeile direkt zu markieren, z.B. wenn Sie Ihre eigenen Navigationskontrollen verwenden möchten. Siehe das Kapitel über GMOCCAPY.

  • [Widgetname].selection_mask = ("Werkzeug", "Rot", "G5x") +
    Diese Zeilen sind im Bearbeitungsmodus NICHT auswählbar.

  • [Widgetname].set_names([['G54','Default'],["G55", "Vice1"],['Rot','Rotational']]) +
    Damit können Sie den Text der Spalte "T" in jeder beliebigen Zeile festlegen. +
    Es handelt sich um eine Liste von Offset-Namen/Benutzernamen-Paaren. +
    Der Standardtext ist derselbe wie der Offsetname.

  • [Widgetname].get_names()` +
    Diese Funktion gibt eine Liste von Paaren aus Zeilen-Schlüsselwort/Benutzername zurück. +
    Die Spalte mit den Benutzernamen ist editierbar, so dass das Speichern dieser Liste benutzerfreundlich ist. +
    Siehe set_names oben.

images/offsetpage.png
Abbildung 18. Beispiel für eine Offset-Seite

6.27. HAL_sourceview-Widget

Dies ist für die Anzeige und einfache Bearbeitung von G-Code. Es sucht nach .ngc-Hervorhebungsspezifikationen in ~/share/gtksourceview-2.0/language-specs/. Die aktuell laufende Zeile wird hervorgehoben.

Mit externem Python-Glue-Code kann dies:

  • Nach Text suchen, Änderungen rückgängig machen und Wiederherstellen,

  • für die Auswahl von Programmzeilen genutzt werden.

6.27.1. Direkte Programmsteuerung

Es gibt Python-Methoden zur Steuerung des Widgets:

  • [widget name].redo() +
    Wiederholung einer Ebene von Änderungen.

  • [widget name].undo()` +
    Rückgängig machen einer Ebene von Änderungen

  • [Widgetname].text_search(direction=True,mixed_case=True,text='G92') +
    Sucht vorwärts (direction = True) oder rückwärts, +
    Sucht mit gemischter Groß- und Kleinschreibung (mixed_case = True) oder exakter Übereinstimmung

  • [Widgetname].set_line_number(Zeilennummer) +
    Setzt die hervorzuhebende Zeile. +
    Verwendet die Zeilennummern der Quellansicht.

  • [Widgetname].get_line_number() +
    Gibt die aktuell hervorgehobene Zeile zurück.

  • [Widget-Name].line_up()` +
    Verschiebt die markierte Zeile um eine Zeile nach oben.

  • [Name des Widgets].line_down()
    Verschiebt die markierte Zeile um eine Zeile nach unten.

  • [Widgetname].load_file('Dateiname')
    Lädt eine Datei.
    Die Verwendung von None (keine Zeichenkette für den Dateinamen) lädt das gleiche Programm erneut.

  • [Widget-Name].get_filename()
    FIXME Beschreibung

images/hal_sourceview.png
Abbildung 19. Quellen-Ansicht (engl. sourceview) Beispiel

6.28. MDI-Geschichte

Dient zur Anzeige und Eingabe von MDI-Codes.
Sie wird automatisch ausgegraut, wenn MDI nicht verfügbar ist, z. B. bei Notaus und laufenden Programmen.

6.28.1. Eigenschaften

font_size_tree

Ganzzahliger Wert zwischen 8 und 96.
Ändert die Standardschriftgröße der Baumansicht auf den ausgewählten Wert.

font_size_entry

Ganzzahliger Wert zwischen 8 und 96. +
Ändert die Standardschriftgröße der Baumansicht auf den ausgewählten Wert.

use_double_click

Boolean, True aktiviert die Maus-Doppelklick-Funktion und ein Doppelklick auf einen Eintrag sendet diesen Befehl.
Es wird nicht empfohlen, diese Funktion auf echten Maschinen zu verwenden, da ein Doppelklick auf einen falschen Eintrag zu gefährlichen Situationen führen kann.

6.28.2. Direkte Programmsteuerung

Verwenden Sie goobject, um die oben aufgeführten Eigenschaften einzustellen:

[widget name].set_property("font_size_tree",10)
[widget name].set_property("font_size_entry",20)
[widget name].set_property("use_double_click",False)

6.29. Animierte Funktionsdiagramme: HAL-Widgets in einer Bitmap

Für einige Anwendungen kann es wünschenswert sein, ein Hintergrundbild zu haben - wie ein Funktionsdiagramm - und Widgets an geeigneten Stellen in diesem Bild zu positionieren. Eine gute Kombination ist das Setzen eines Bitmap-Hintergrundbildes, z.B. aus einer .png-Datei, das Festlegen der Größe des GladeVCP-Fensters und die Verwendung des Glade Fixed-Widgets zur Positionierung von Widgets auf diesem Bild. Der Code für das folgende Beispiel ist in configs/apps/gladevcp/animated-backdrop zu finden:

images/small-screenshot.png
Abbildung 20. HAL-Widgets in einem Bitmap Beispiel

7. Referenz zu Aktions-Widgets

GladeVCP enthält eine Sammlung von "vorgefertigten Aktionen" (engl. canned actions) namens VCP Action Widgets für den Glade-Benutzeroberflächeneditor.

Anmerkung

Anders als die mit HAL-Pins interagierenden HAL-Widgets, interagieren VCP-Aktionen mit LinuxCNC und dem G-Code-Interpreter.

VCP Action Widgets sind von dem Gtk.Action Widget abgeleitet.

Das Action-Widget in Kürze:

  • Es ist ein in Glade verfügbares Objekt

  • Es hat für sich genommen kein optisches Erscheinungsbild

  • Sein Zweck: Eine sichtbare, empfindliche UI-Komponente wie ein Menü, eine Werkzeugschaltfläche oder eine Schaltfläche mit einem Befehl zu verknüpfen. Siehe die Eigenschaft "General→Related→Action" dieser Widgets.

  • Die "vorgefertigte Aktion" (nicht-veränderbares Makro, engl. canned action) wird ausgeführt, wenn die zugehörige UI-Komponente ausgelöst wird (Tastendruck, Menüklick..).

  • Es bietet eine einfache Möglichkeit, Befehle auszuführen, ohne auf Python-Programmierung zurückgreifen zu müssen.

Das Erscheinungsbild der VCP-Aktionen in Glade sieht in etwa wie folgt aus:

images/vcp-actions.png
Abbildung 21. Action-Widgets

Hover über Werkzeugspitzen (engl. tooltips) liefert eine Beschreibung.

7.1. VCP Action-Widgets

VCP Action-Widgets sind einmalige Widgets. Sie implementieren eine einzelne Aktion und sind für die Verwendung in einfachen Schaltflächen, Menüeinträgen oder Options-/Kontrollgruppen vorgesehen.

7.2. VCP Action Python

Dieses Widget wird verwendet, um kleinen, beliebigen Python-Code auszuführen.

Der Befehlsstring kann spezielle Schlüsselwörter für den Zugriff auf wichtige Funktionen enthalten.

  • ACTION für den Zugriff auf die ACTION-Befehlsbibliothek.

  • GSTAT für den Zugriff auf die Gstat-Bibliothek für Statusmeldungen.

  • INFO für den Zugriff auf gesammelte Daten aus der INI-Datei.

  • HAL für den Zugriff auf das HAL linuxcnc Python-Modul

  • STAT für den Zugriff auf LinuxCNC’s rohen Status über das LinuxCNC Python Modul.

  • CMD für den Zugriff auf LinuxCNC-Befehle über das LinuxCNC-Python-Modul.

  • EXT für den Zugriff auf die Handler-Dateifunktionen, falls verfügbar.

  • linuxcnc für den Zugriff auf das LinuxCNC-Python-Modul.

  • self für den Zugriff auf die Widget-Instanz.

  • dir für den Zugriff auf die Handler-Attributliste.

Es gibt Optionen für

  • wählen Sie aus, wann das Widget aktiv sein soll,

  • den Modus einstellen, bevor der Befehl ausgeführt wird.

Beispiel für einen Befehl, um einfach eine Nachricht auf dem Terminal zu auszugeben:

print('Aktion aktiviert')

Beispiel für einen Befehl, um die Maschine in den Aus-Zustand zu versetzen:

CMD.state(linuxcnc.STATE_OFF)

Beispiel für einen Befehl für den Aufruf einer Handler-Funktion, die Daten übergibt:

EXT.on_button_press(self, 100)

Sie können ein Semicolon verwenden, um mehrere Befehle zu trennen;

print('Set Machine Off');CMD.state(linuxcnc.STATE_OFF)

Weitere Informationen zu INFO und ACTION finden Sie hier: GladeVCP Libraries modules.

Weitere Informationen zu GStat finden Sie hier: GStat.

7.3. VCP ToggleAction-Widgets

Dies sind bi-modale Widgets. Sie implementieren zwei Aktionen oder verwenden einen zweiten (normalerweise gedrückten) Zustand, um anzuzeigen, dass gerade eine Aktion ausgeführt wird. Toggle-Aktionen sind für die Verwendung in ToggleButtons, ToggleToolButtons oder zum Umschalten von Menüpunkten gedacht. Ein einfaches Beispiel ist die ESTOP (engl. für Notaus) Umschalttaste.

Derzeit sind die folgenden Widgets verfügbar:

  • Der ESTOP Toggle sendet ESTOP oder ESTOP_RESET Befehle an LinuxCNC, abhängig von seinem Zustand.

  • Die Umschaltfunktion ON/OFF sendet die Befehle STATE_ON und STATE_OFF.

  • Pause/Fortsetzen sendet die Befehle AUTO_PAUSE oder AUTO_RESUME.

Die folgenden Toggle-Aktionen haben nur einen zugehörigen Befehl und verwenden den Zustand "gedrückt", um anzuzeigen, dass der angeforderte Vorgang ausgeführt wird:

  • Der Run-Toggle sendet einen AUTO_RUN-Befehl und wartet im gedrückten Zustand, bis der Interpreter wieder im Leerlauf ist.

  • Der Stop-Schalter ist inaktiv, bis der Interpreter in den aktiven Zustand übergeht (d.h. G-Code ausführt) und dem Benutzer dann erlaubt, den Befehl AUTO_ABORT zu senden.

  • Der MDI-Umschalter sendet einen bestimmten MDI-Befehl und wartet im inaktiven Zustand "gedrückt" auf dessen Ausführung.

7.4. Die Action_MDI Toggle und Action_MDI Widgets

Diese Widgets bieten eine Möglichkeit, beliebige MDI-Befehle auszuführen.
Das Action_MDI-Widget wartet nicht auf die Beendigung des Befehls, wie es das Action_MDI-Toggle tut, das deaktiviert bleibt, bis der Befehl beendet ist.

7.5. Ein einfaches Beispiel: Ausführen eines MDI-Befehls bei Button-Druck

configs/apps/gladevcp/mdi-command-example/whoareyou.ui ist eine Glade UI-Datei, welche die Grundlagen vermittelt:

  1. Öffnen Sie es in Glade und studieren Sie, wie es gemacht wird.

  2. Starten Sie AXIS, und starten Sie es dann von einem Terminalfenster aus mit gladevcp whoareyou.ui.

  3. Sehen Sie sich die Aktion hal_action_mdi1 und ihre Eigenschaft MDI command an - diese führt einfach (MSG, "Hi, I'm an VCP_Action_MDI") aus, so dass in AXIS ein Nachrichten-Popup erscheinen sollte, etwa so:

images/whoareyou.png
Abbildung 22. Action_MDI Einfaches Beispiel

Sie werden feststellen, dass die mit der Aktion Action_MDI verbundene Schaltfläche ausgegraut ist, wenn die Maschine ausgeschaltet ist, sich im E-Stop befindet oder der Interpreter läuft. Sie wird automatisch aktiv, wenn die Maschine eingeschaltet ist und sich nicht mehr im Notaus-Modus befindet und das Programm im Leerlauf ist.

7.6. Parameterübergabe mit Action_MDI- und ToggleAction_MDI-Widgets

Optional können bei "MDI Befehl"-Zeichenketten Parameter ersetzt werden, bevor sie an den Interpreter übergeben werden. Parameter können derzeit Namen von HAL-Pins in der GladeVCP-Komponente sein. So funktioniert es:

  • Nehmen Sie an, Sie haben eine HAL SpinBox mit dem Namen Geschwindigkeit, und Sie wollen deren aktuellen Wert als Parameter in einem MDI-Befehl übergeben.

  • Die HAL SpinBox hat einen HAL-Pin vom Typ float mit dem Namen speed-f (siehe HalWidgets-Beschreibung).

  • für die obige HAL SpinBox könnten wir (MSG, "Die Geschwindigkeit ist: ${geschwindigkeit-f}") verwenden, um zu zeigen, was passiert.

Die Beispiel-UI-Datei ist "configs/apps/gladevcp/mdi-command-example/speed.ui". So sieht das Ergebnis aus, wenn man sie ausführt:

images/speed.png
Abbildung 23. Action_MDI Parameterübergabe Beispiel

7.7. Ein fortgeschrittenes Beispiel: Übergabe von Parametern an eine O-Wort-Unterroutine

Es ist völlig in Ordnung, eine O-Wort-Unterroutine in einem MDI-Befehl aufzurufen und HAL-Pin-Werte als aktuelle Parameter zu übergeben. Eine Beispiel-UI-Datei befindet sich in configs/apps/gladevcp/mdi-command-example/owordsub.ui.

Legen Sie nc_files/gladevcp_lib/oword.ngc so ab, dass AXIS es finden kann, und führen Sie gladevcp owordsub.ui in einem Terminalfenster aus. Das sieht dann so aus:

images/oword.png
Abbildung 24. Action_MDI Erweitertes Beispiel

7.8. Vorbereitung einer MDI-Aktion und anschließendes Aufräumen

Der LinuxCNC G-Code-Interpreter hat einen einzigen globalen Satz von Variablen, wie Vorschub, Spindeldrehzahl, relative/absolute Modus und andere. Wenn Sie G-Code-Befehle oder O-Wort-Subs verwenden, könnten einige dieser Variablen durch den Befehl oder Unterprogramm geändert werden - zum Beispiel wird ein Antasten Unterprogramm sehr wahrscheinlich den Vorschubwert ziemlich niedrig eingestellt. Ohne weitere Vorkehrungen wird Ihre vorherige Vorschubeinstellung durch den Wert des Sondierungsunterprogramms überschrieben.

Um mit diesem überraschenden und unerwünschten Nebeneffekt eines bestimmten O-Wort-Unterprogramms oder einer G-Code-Anweisung, die mit einem LinuxCNC ToggleAction_MDI ausgeführt wird, umzugehen, können Sie pre-MDI- und post-MDI-Handler mit einem bestimmten LinuxCNC ToggleAction_MDI verbinden. Diese Handler sind optional und bieten die Möglichkeit, den Zustand vor der Ausführung der MDI-Aktion zu speichern und danach wieder auf die vorherigen Werte zurückzusetzen. Die Signalnamen sind mdi-command-start und mdi-command-stop; die Namen der Handler können in Glade wie jeder andere Handler gesetzt werden.

Hier ist ein Beispiel, wie ein Vorschubwert durch solche Handler gespeichert und wiederhergestellt werden könnte (beachten Sie, dass LinuxCNC Befehls- und Statuskanäle als self.linuxcnc und self.stat durch die VCP_ActionBase Klasse verfügbar sind):

    def on_mdi_command_start(self, action, userdata=None):
        action.stat.poll()
        self.start_feed = action.stat.settings[1]

    def on_mdi_command_stop(self, action, userdata=None):
        action.linuxcnc.mdi('F%.1f' % (self.start_feed))
        while action.linuxcnc.wait_complete() == -1:
            pass

Nur das Toggle-Widget Action_MDI unterstützt diese Signale.

Anmerkung

In einer späteren Version von LinuxCNC, werden die neuen M-Codes M70-M72 verfügbar sein. Sie machen das Speichern von Zustand vor einem Unterprogramm aufrufen, und Wiederherstellen von Zustand bei der Rückkehr viel einfacher.

7.9. Verwendung des LinuxCNC Stat-Objekts zum Umgang mit Statusänderungen

Viele Aktionen hängen vom LinuxCNC-Status ab - ist es im manuellen, MDI- oder Auto-Modus? Läuft ein Programm, pausiert es oder ist es im Leerlauf? Sie können keinen MDI-Befehl starten, während ein G-Code-Programm läuft, also muss dies beachtet werden. Viele LinuxCNC-Aktionen kümmern sich selbst darum, und die zugehörigen Schaltflächen und Menüeinträge sind deaktiviert, wenn die Operation gerade nicht möglich ist.

Bei der Verwendung von Python-Ereignishandlern - die sich auf einer niedrigeren Ebene als Actions befinden - muss man sich selbst um den Umgang mit Statusabhängigkeiten kümmern. Für diesen Zweck gibt es das LinuxCNC Stat-Widget: um LinuxCNC-Statusänderungen mit Event-Handlern zu verknüpfen.

LinuxCNC Stat hat keine sichtbare Komponente - Sie fügen es einfach mit Glade zu Ihrer Benutzeroberfläche hinzu. Einmal hinzugefügt, können Sie Handler mit den folgenden Signalen verknüpfen:

  • zustandsbezogen:

    • state-estop: ausgegeben, wenn die Notaus-Bedingung eintritt,

    • state-estop-reset: ausgegeben, wenn die Maschine zurückgesetzt wird,

    • "state-on": wird beim Einschalten des Geräts ausgegeben,

    • state-off: wird ausgegeben, wenn die Maschine ausgeschaltet wird.

  • Modus-bezogen:

    • mode-manual: wird ausgegeben, wenn LinuxCNC in den manuellen Modus wechselt,

    • mode-mdi: ausgegeben, wenn LinuxCNC in den MDI-Modus wechselt,

    • mode-auto: ausgegeben, wenn LinuxCNC in den automatischen Modus wechselt,

  • Interpreter-bezogen: wird ausgegeben, wenn der G-Code-Interpreter in diesen Modus wechselt

    • interp-run

    • interp-idle

    • interp-paused

    • interp-reading

    • interp-waiting

    • file-loaded

    • line-changed

  • Referenzfart-bezogen: ausgegeben, wenn LinuxCNC referenziert ist oder nicht

    • all-homed

    • nicht-all-homed

8. GladeVCP-Programmierung

8.1. Benutzerdefinierte Aktionen

Die meisten Widgetsets und die dazugehörigen Editoren für die Benutzeroberfläche unterstützen das Konzept der Callbacks, d.h. Funktionen im vom Benutzer geschriebenen Code, die ausgeführt werden, wenn in der Benutzeroberfläche "etwas passiert" - Ereignisse wie Mausklicks, eingegebene Zeichen, Mausbewegungen, Timer-Ereignisse, das Ein- und Ausblenden von Fenstern und so weiter.

HAL-Ausgabe-Widgets bilden typischerweise Eingabe-Ereignisse wie einen Tastendruck mittels eines solchen - vordefinierten - Callbacks auf eine Wertänderung des zugehörigen HAL-Pins ab. In PyVCP ist dies wirklich die einzige Art der Ereignisbehandlung, die unterstützt wird - etwas Komplexeres, wie die Ausführung von MDI-Befehlen zum Aufruf eines G-Code-Unterprogramms, wird nicht unterstützt.

Innerhalb von GladeVCP sind HAL-Pin-Änderungen nur ein Typ der allgemeinen Klasse von Ereignissen (Signale genannt) in GTK+. Die meisten Widgets können solche Signale auslösen, und der Glade-Editor unterstützt die Verknüpfung eines solchen Signals mit einem Python-Methoden- oder Funktionsnamen.

Wenn Sie sich entscheiden, benutzerdefinierte Aktionen zu verwenden, ist es Ihre Aufgabe, ein Python-Modul zu schreiben, dessen Klassenmethoden - oder im einfachen Fall nur Funktionen - in Glade als Event-Handler referenziert werden können. GladeVCP bietet eine Möglichkeit, Ihr(e) Modul(e) beim Start zu importieren und wird Ihre Event-Handler automatisch mit den Widgetsignalen verknüpfen, wie sie in der Glade-UI-Beschreibung festgelegt sind.

8.2. Core-Bibliothek

Es gibt drei Bibliotheken mit Funktionen, die zur Programmierung von GladeVCP verwendet werden können.

  • Info: sammelt Details aus der INI-Datei.

  • Action: Eine Sammlung von Funktionen zum Ändern von LinuxCNC-Zuständen.

  • Status: Meldet den Status von LinuxCNC. Es führt intern "Gstat" aus ("wrapt").

Importieren und Instanziieren der Bibliotheken:

from gladevcp.core import Info, Action

ACTION = Action()
INFO = Info()

Verwendung der Bibliotheksfunktionen:

print(INFO.MACHINE_IS_METRIC)
ACTION.SET_ERROR_MESSAGE('Something went wrong')

Weitere Informationen finden Sie hier : GladeVCP Libraries modules. Es gibt eine Beispielkonfiguration, welche die Verwendung der Kernbibliothek mit GladeVCPs Action-Python-Widgets und mit einer Python-Handler-Datei demonstriert. Versuchen Sie, sim/axis/gladevcp/gladevcp_panel_tester zu laden.

8.3. Ein Beispiel: Hinzufügen benutzerdefinierter Callback-Funktionen in Python

Dies ist nur ein minimales Beispiel, um die Idee zu vermitteln - Details werden im restlichen Teil dieses Abschnitts erläutert.

GladeVCP kann nicht nur HAL-Pins manipulieren oder anzeigen, man kann auch reguläre Event-Handler in Python schreiben. Dies kann unter anderem zur Ausführung von MDI-Befehlen verwendet werden. So wird es gemacht:

Schreiben Sie ein Python-Modul wie folgt und speichern Sie es z. B. als handlers.py:

nhits = 0
def on_button_press(gtkobj,data=None):
    global nhits
    nhits += 1
    gtkobj.set_label("hits: %d" % nhits)

Definieren Sie in Glade eine Schaltfläche oder eine HAL-Schaltfläche, wählen Sie die Registerkarte "Signale" und wählen Sie in den Eigenschaften von GtkButton die Zeile "pressed". Geben Sie dort "on_button_press" ein und speichern Sie die Glade-Datei.

Fügen Sie dann die Option -u handlers.py in die GladeVCP-Befehlszeile ein. Wenn Ihre Event-Handler über mehrere Dateien verteilt sind, fügen Sie einfach mehrere -u <pyfilename> Optionen hinzu.

Wenn Sie nun auf die Schaltfläche drücken, sollte sich ihre Beschriftung ändern, da sie in der Callback-Funktion festgelegt wurde.

Was das Flag -u bewirkt: alle Python-Funktionen in dieser Datei werden gesammelt und als potentielle Callback-Handler für Ihre Gtk-Widgets eingerichtet - sie können über die Glade-Registerkarten "Signale" referenziert werden. Die Callback-Handler werden mit der jeweiligen Objektinstanz als Parameter aufgerufen, wie die GtkButton-Instanz oben, so dass Sie jede GtkButton-Methode von dort aus anwenden können.

Oder machen Sie etwas Nützlicheres, wie den Aufruf eines MDI-Befehls!

8.4. HAL-Wertänderungs-Ereignisse

HAL-Eingangs-Widgets, wie z.B. eine LED, assoziieren automatisch ihren HAL-Pin-Status (an/aus) mit dem optischen Erscheinungsbild des Widgets (LED leuchtet/dunkelt).

Über diese eingebaute Funktionalität hinaus kann man jedem HAL-Pin, auch denen von vordefinierten HAL-Widgets, einen Änderungs-Callback zuordnen. Dies passt gut zu der ereignisgesteuerten Struktur einer typischen Widget-Anwendung: Jede Aktivität, sei es ein Mausklick, eine Taste, ein abgelaufener Timer oder die Änderung des Wertes eines HAL-Pins, erzeugt einen Callback und wird durch denselben orthogonalen Mechanismus behandelt.

Für benutzerdefinierte HAL-Pins, die nicht mit einem bestimmten HAL-Widget verbunden sind, lautet der Signalname value-changed. Siehe den Abschnitt AL Pins hinzufügen weiter unten für Details.

HAL Widgets werden mit einem vordefinierten Signal namens hal-pin-changed geliefert. Siehe den Abschnitt HAL Widgets für Details.

8.5. Programmiermodell

Das Gesamtkonzept sieht folgendermaßen aus:

  • Entwerfen Sie Ihre Benutzeroberfläche mit Glade, und legen Sie Signal-Handler fest, wenn Sie Aktionen mit einem Widget verbinden möchten.

  • Schreiben Sie ein Python-Modul, das aufrufbare Objekte enthält (siehe "Handler-Modelle" unten).

  • Übergeben Sie den Pfadnamen Ihres Moduls an GladeVCP mit der Option -u <modul>.

  • GladeVCP importiert das Modul, prüft es auf Signalhandler und verbindet sie mit dem Widgetbaum.

  • Die Hauptereignisschleife wird ausgeführt.

8.5.1. Das einfache Handler-Modell

Für einfache Aufgaben reicht es aus, Funktionen zu definieren, die nach den Glade-Signalhandlern benannt sind. Diese werden aufgerufen, wenn das entsprechende Ereignis im Widgetbaum eintritt. Hier ist ein triviales Beispiel - es nimmt an, dass das pressed Signal eines Gtk Buttons oder HAL Buttons mit einem Callback namens on_button_press verknüpft ist:

nhits = 0
def on_button_press(gtkobj,data=None):
    global nhits
    nhits += 1
    gtkobj.set_label("hits: %d" % nhits)

Fügen Sie diese Funktion in eine Python-Datei ein und führen Sie sie wie folgt aus:

gladevcp -u <myhandler>.py mygui.ui

Beachten Sie, dass die Kommunikation zwischen Handlern über globale Variablen erfolgen muss, was nicht gut skalierbar und absolut unpythonisch ist. Aus diesem Grund haben wir das klassenbasierte Handler-Modell entwickelt.

8.5.2. Das klassenbasierte Handler-Modell

Die Idee dabei ist: Handler werden mit Klassenmethoden verknüpft. Die zugrundeliegende(n) Klasse(n) werden beim Start von GladeVCP instanziiert und inspiziert und als Signal-Handler mit dem Widget-Baum verknüpft. Die Aufgabe ist nun also zu schreiben:

  • Eine oder mehrere Klassendefinition(en) mit einer oder mehreren Methoden, in einem Modul oder aufgeteilt auf mehrere Module,

  • eine Funktion get_handlers in jedem Modul, die eine Liste von Klasseninstanzen an GladeVCP zurückgibt - ihre Methodennamen werden mit Signalhandlern verknüpft.

Hier ist ein minimales benutzerdefiniertes Handler-Beispielmodul:

class MyCallbacks :
    def on_this_signal(self,obj,data=None):
        print("this_signal happened, obj=",obj)

def get_handlers(halcomp,builder,useropts):
    return [MyCallbacks ()]

Jetzt wird on_this_signal als Signalhandler für Ihren Widgetbaum verfügbar sein.

8.5.3. GladeVCP-spezifische Signale

Für GladeVCP-Panels, die auf HAL-Eingaben reagieren, kann es wichtig sein, dass der Handler-Code erkennen kann, dass das GladeVCP-Panel gerade aktiv und angezeigt ist. Zum Beispiel könnte ein Panel innerhalb der Touchy-Schnittstelle durchaus eine Aktion ausführen müssen, wenn der mit touchy.cycle-start verbundene Schalter betätigt wird (so wie die nativen Tabs unterschiedlich auf die gleiche Schaltfläche reagieren).
Um dies zu ermöglichen, wird ein Signal von der GUI (zum Zeitpunkt des Schreibens nur Touchy) an die eingebettete Registerkarte gesendet. Das Signal ist vom Typ "Gladevcp" und die beiden gesendeten Nachrichten sind "Sichtbar" und "Ausgeblendet". (Beachten Sie, dass die Signale eine feste Länge von 20 Zeichen haben, so dass nur die ersten Zeichen in einem Vergleich verwendet werden sollten, daher die [:7] unten). Ein Beispiel für einen Handler für diese Signale ist:

    # This catches our messages from another program
    def event(self,w,event):
        print(event.message_type,event.data)
        if event.message_type == 'Gladevcp':
            if event.data[:7] == 'Visible':
                self.active = True
            else:
                self.active = False

    # connect to client-events from the host GUI
    def on_map_event(self, widget, data=None):
        top = widget.get_toplevel()
        print("map event")
        top.connect('client-event', self.event)

8.5.4. Das get_handlers Protokoll

Wenn GladeVCP bei der Modulinspektion eine Funktion get_handlers findet, ruft es diese wie folgt auf:

get_handlers(halcomp,builder,useropts)

Die Argumente sind:

  • halcomp - bezieht sich auf die im Bau befindliche HAL-Komponente,

  • builder - Widget-Baum - Ergebnis des Lesens der UI-Definition (entweder auf ein Objekt vom Typ GtkBuilder oder libglade verweisend),

  • useropts - eine Liste von Zeichenfolgen, die von der GladeVCP-Befehlszeile mit der Option -U <useropts> gesammelt werden.

GladeVCP untersucht dann die Liste der Klasseninstanzen und ruft deren Methodennamen ab. Qualifizierende Methodennamen werden als Signalhandler mit dem Widgetbaum verbunden. Nur Methodennamen, die nicht mit einem _ (Unterstrich) beginnen, werden berücksichtigt.

Beachten Sie, dass unabhängig davon, ob Sie das libglade- oder das neue GtkBuilder-Format für Ihre Glade-Benutzeroberfläche verwenden, Widgets immer als builder.get_object(<widgetname>) bezeichnet werden können. Außerdem ist die komplette Liste der Widgets als builder.get_objects() verfügbar, unabhängig vom UI-Format.

8.6. Initialisierungssequenz

Es ist wichtig zu wissen, in welchem Zustand die Funktion get_handlers() aufgerufen wird, damit Sie wissen, was Sie dort sicher tun können und was nicht. Zunächst werden die Module in der Befehlszeilenreihenfolge importiert und initialisiert. Nach erfolgreichem Import wird get_handlers() im folgenden Zustand aufgerufen:

  • Der Widgetbaum ist erstellt, aber noch nicht realisiert (es wurde noch kein Toplevel window.show() ausgeführt).

  • Die halcomp HAL-Komponente ist eingerichtet und alle Pins des HAL-Widgets wurden bereits hinzugefügt.

  • Es ist sicher, weitere HAL-Pins hinzuzufügen, da halcomp.ready() zu diesem Zeitpunkt noch nicht aufgerufen wurde, so dass Sie Ihre eigenen Pins hinzufügen können, zum Beispiel in der Klasse init()-Methode.

Nachdem alle Module importiert und die Methodennamen extrahiert wurden, werden die folgenden Schritte durchgeführt:

  • Alle qualifizierenden Methodennamen werden mit connect_signals()/signal_autoconnect() mit dem Widget-Baum verbunden (abhängig von der Art der importierten Benutzeroberfläche - GtkBuilder im Vergleich zum alten libglade-Format).

  • Die HAL-Komponente wird mit halcomp.ready() abgeschlossen.

  • Wenn eine Fenster-ID als Argument übergeben wurde, wird der Widget-Baum neu geparented, um in diesem Fenster zu laufen, und Glades Toplevel window1 wird aufgegeben (siehe FAQ).

  • Wenn eine HAL-Befehlsdatei mit -H halfile übergeben wurde, wird sie mit halcmd ausgeführt.

  • Die Gtk-Hauptschleife wird ausgeführt.

Wenn also Ihre Handler-Klasse initialisiert wird, sind alle Widgets vorhanden, aber noch nicht realisiert (auf dem Bildschirm angezeigt). Und die HAL-Komponente ist auch noch nicht fertig, so dass es unsicher ist, auf die Werte der Pins in Ihrer Methode "init_()" zuzugreifen.

Wenn Sie einen Callback haben wollen, der beim Programmstart ausgeführt wird, nachdem es sicher ist, auf die HAL-Pins zuzugreifen, dann verbinden Sie einen Handler mit dem realize-Signal des Top-Level-Fensters1 (was sein einziger wirklicher Zweck sein könnte). An diesem Punkt ist GladeVCP mit allen Setup-Aufgaben fertig, die HAL-Datei wurde ausgeführt, und GladeVCP ist dabei, in die Gtk-Hauptschleife einzutreten.

8.7. Mehrere Callbacks mit demselben Namen

Innerhalb einer Klasse müssen die Methodennamen eindeutig sein. Es ist jedoch in Ordnung, wenn mehrere Klasseninstanzen mit identisch benannten Methoden durch get_handlers() an GladeVCP übergeben werden. Wenn das entsprechende Signal auftritt, werden diese Methoden in der Definitionsreihenfolge aufgerufen - Modul für Modul, und innerhalb eines Moduls in der Reihenfolge, in der die Klasseninstanzen von "get_handlers()" zurückgegeben werden.

8.8. Die GladeVCP -U <useropts> Flag

Anstatt GladeVCP für jede denkbare Option zu erweitern, die für eine Handler-Klasse potentiell nützlich sein könnte, können Sie das Flag -U <Benutzeroption> verwenden (auf Wunsch wiederholt). Dieses Flag sammelt eine Liste von <useroption>-Strings. Diese Liste wird an die Funktion get_handlers() übergeben (Argument useropts). Es steht Ihrem Code frei, diese Zeichenfolgen nach eigenem Ermessen zu interpretieren. Eine mögliche Verwendung wäre, sie in der Funktion get_handlers() wie folgt an die Python-Funktion exec zu übergeben:

debug = 0
...
def get_handlers(halcomp,builder,useropts):
    ...
    global debug # assuming there's a global var
    for cmd in useropts:
        exec cmd in globals()

Auf diese Weise können Sie beliebige Python-Anweisungen an Ihr Modul übergeben, zum Beispiel durch die Option gladevcp -U:

gladevcp -U debug=42 -U "print 'debug=%d' % debug" ...

Dies sollte debug auf 2 setzen und bestätigen, dass Ihr Modul es tatsächlich getan hat.

8.9. Persistente Variablen in GladeVCP

Ein ärgerlicher Aspekt von GladeVCP in seiner früheren Form und PyVCP ist die Tatsache, dass Sie Werte und HAL-Pins durch Texteingabe, Schieberegler, Spin-Boxen, Toggle-Buttons usw. ändern können, aber ihre Einstellungen werden nicht gespeichert und beim nächsten Lauf von LinuxCNC wiederhergestellt - sie beginnen mit dem Standardwert, wie in der Panel-oder Widget-Definition eingestellt.

GladeVCP verfügt über einen einfach zu bedienenden Mechanismus zum Speichern und Wiederherstellen des Zustands von HAL-Widgets und Programmvariablen (in der Tat jedes Instanzattribut vom Typ int, float, bool oder string).

Dieser Mechanismus verwendet das weit verbreitete INI-Dateiformat, um dauerhafte Attribute zu speichern und wieder zu laden.

Persistenz, Programmversionen und die Signaturprüfung

Stellen Sie sich vor, Sie benennen Widgets in Glade um, fügen sie hinzu oder löschen sie: Eine INI-Datei aus einer früheren Programmversion oder eine völlig andere Benutzeroberfläche könnte den Zustand nicht richtig wiederherstellen, da sich Variablen und Typen geändert haben könnten.

GladeVCP erkennt diese Situation durch eine Signatur, die von allen Objektnamen und -typen abhängt, die gespeichert sind und wiederhergestellt werden sollen. Im Falle einer Nichtübereinstimmung der Signatur wird eine neue INI-Datei mit Standardeinstellungen erzeugt.

8.10. Verwendung persistenter Variablen

Wenn Sie möchten, dass der Status des Gtk-Widgets, die Werte des HAL-Widgets-Ausgabepins und/oder die Klassenattribute Ihrer Handler-Klasse über Aufrufe hinweg erhalten bleiben, gehen Sie wie folgt vor:

  • Importieren Sie das Modul gladevcp.persistence.

  • Entscheiden Sie, welche Instanzattribute und deren Standardwerte Sie beibehalten wollen, falls vorhanden.

  • Entscheiden Sie, welche Widgets ihren Zustand beibehalten sollen.

  • Beschreiben Sie diese Entscheidungen in der __init__() Methode Ihrer Handler-Klasse durch ein verschachteltes Wörterbuch wie folgt:

def __init__(self, halcomp,builder,useropts):
    self.halcomp = halcomp
    self.builder = builder
    self.useropts = useropts
    self.defaults = {
        # die folgenden Namen werden als Methodenattribute gespeichert/wiederhergestellt
        # Der Mechanismus zum Speichern/Wiederherstellen ist stark typisiert - der Typ der Variablen wird vom Typ des
        # Initialisierungswertes abgeleitet. Derzeit unterstützte Typen sind: int, float, bool, string
        IniFile.vars : { 'nhits' : 0, 'a': 1.67, 'd': True ,'c' : "ein String"},
        # zum Speichern/Wiederherstellen aller Widgets, die auch nur im Entferntesten Sinn machen könnten, fügen Sie dies hinzu:
        IniFile.widgets : widget_defaults(builder.get_objects())
        # Eine sinnvolle Alternative wäre es, nur den Zustand aller HAL-Ausgabe-Widgets beizubehalten:
        # IniFile.widgets: widget_defaults(select_widgets(self.builder.get_objects(), hal_only=True,output_only = True)),
    }

Dann verknüpfen Sie eine INI-Datei mit diesem Deskriptor:

self.ini_filename = __name__ + '.ini'
self.ini = IniFile(self.ini_filename,self.defaults,self.builder)
self.ini.restore_state(self)

Nach restore_state() werden die Attribute von self gesetzt, wenn sie wie folgt ablaufen:

self.nhits = 0
self.a = 1.67
self.d = True
self.c = "eine Zeichenkette"

Beachten Sie, dass die Typen gespeichert und bei der Wiederherstellung beibehalten werden. In diesem Beispiel wird davon ausgegangen, dass die INI-Datei nicht vorhanden war oder die Standardwerte aus self.defaults enthielt.

Nach dieser Beschwörung können Sie die folgenden IniFile-Methoden verwenden:

ini.save_state(obj)

Speichert die Attribute von objs gemäß dem IniFile.vars-Wörterbuch und den Zustand des Widgets wie in IniFile.widgets beschrieben in self.defaults.

ini.create_default_ini()

Erstellen Sie eine INI-Datei mit Standardwerten.

ini.restore_state(obj)

HAL out Pins und obj’s Attribute wie oben gespeichert/initialisiert auf Standard zurücksetzen.

8.11. Speichern des Status beim Herunterfahren von GladeVCP

Um den Zustand des Widgets und/oder der Variablen beim Beenden zu speichern, gehen Sie wie folgt vor:

  • Wählen Sie ein Interieur-Widget aus (Typ ist nicht wichtig, z. B. eine Tabelle).

  • Wählen Sie auf der Registerkarte "Signale" die Option "GtkObject". In der ersten Spalte sollte ein destroy-Signal angezeigt werden.

  • Fügen Sie den Namen des Handlers, z. B. on_destroy, in die zweite Spalte ein.

  • Fügen Sie einen Python-Handler wie unten beschrieben hinzu:

import gtk
...
def on_destroy(self,obj,data=None):
    self.ini.save_state(self)

Dadurch wird der Status gespeichert und GladeVCP ordnungsgemäß heruntergefahren, unabhängig davon, ob das Panel in AXIS eingebettet oder ein eigenständiges Fenster ist.

Achtung

Verwenden Sie nicht window1 (das Toplevel-Fenster), um ein`destroy` (engl. für zerstören)-Event zu verbinden. Aufgrund der Art und Weise, wie ein GladeVCP-Panel mit AXIS interagiert, wenn ein Panel in AXIS eingebettet ist, wird window1 destroy-Ereignisse nicht richtig empfangen. Da jedoch beim Herunterfahren alle Widgets zerstört werden, reicht jedes beliebige aus. Empfohlen: Verwenden Sie ein Widget der zweiten Ebene - zum Beispiel, wenn Sie einen Tabellencontainer in Ihrem Panel haben, verwenden Sie diesen.

Wenn Sie die GladeVCP-Anwendung das nächste Mal starten, sollten die Widgets in dem Zustand angezeigt werden, in dem sie beim Schließen der Anwendung waren.

Achtung

Die GtkWidget-Zeile hat ein ähnlich klingendes destroy-event - nicht verwenden, um sich mit dem on_destroy-Handler zu verbinden, es wird nicht funktionieren - stellen Sie sicher, dass Sie das destroy-Ereignis aus der GtkObject-Zeile verwenden.

8.12. Status speichern, wenn Strg-C gedrückt wird

Standardmäßig reagiert GladeVCP auf ein Ctrl-C-Ereignis mit einem einfachen Beenden - ohne den Status zu speichern. Um sicherzustellen, dass dieser Fall abgedeckt ist, fügen Sie einen Handler-Aufruf on_unix_signal hinzu, der automatisch bei Ctrl-C (eigentlich bei den Signalen SIGINT und SIGTERM) aufgerufen wird. Beispiel:

def on_unix_signal(self,signum,stack_frame):
    print("on_unix_signal(): signal %d received, saving state" % (signum))
    self.ini.save_state(self)

8.13. Manuelle Bearbeitung von INI-Dateien (.ini)

Sie können dies tun, aber beachten Sie, dass die Werte in self.defaults Ihre Änderungen überschreiben, wenn ein Syntax- oder Typfehler in Ihrer Bearbeitung auftritt. Der Fehler wird erkannt, eine Konsolenmeldung weist auf den Fehler hin und die fehlerhafte INI-Datei wird umbenannt und erhält die Endung .BAD. Nachfolgende fehlerhafte INI-Dateien überschreiben frühere .BAD-Dateien.

8.14. Hinzufügen von HAL-Pins

Wenn Sie HAL-Pins benötigen, die nicht mit einem bestimmten HAL-Widget verbunden sind, fügen Sie sie wie folgt hinzu:

import hal_glib
...
# in your handler class __init__():
self.example_trigger = hal_glib.GPin(halcomp.newpin('example-trigger', hal.HAL_BIT, hal.HAL_IN))

Um einen Callback zu erhalten, wenn sich der Wert dieses Pins ändert, verknüpfen Sie einen value-change (engl. für Wert-Änderung) Callback mit diesem Pin, fügen Sie hinzu:

self.example_trigger.connect('value-changed', self._on_example_trigger_change)

und definieren Sie eine Fallback-Methode (oder -Funktion, in diesem Fall lassen Sie den Parameter self weg):

# Hinweis: '_' - diese Methode ist für den Widget-Baum nicht sichtbar.
def _on_example_trigger_change(self,pin,userdata=None):
    print("Pin-Wert geändert in:" % (pin.get()))

8.15. Hinzufügen von Timern

Da GladeVCP Gtk-Widgets verwendet, die sich auf die Basisklasse PyGObject stützen, ist die volle GLib-Funktionalität verfügbar. Hier ist ein Beispiel für einen Timer-Callback:

def _on_timer_tick(self,userdata=None):
    ...
    return True # um den Timer neu zu starten; return False für on-shot
...
# Demonstration eines langsamen Hintergrund-Timers - Granularität ist eine Sekunde
# für einen schnelleren Timer (Granularität 100 ms), verwenden Sie dies:
# GLib.timeout_add(100, self._on_timer_tick,userdata) # 10Hz
GLib.timeout_add_seconds(1, self._on_timer_tick)

8.16. HAL-Widget-Eigenschaften programmatisch einstellen

Bei Glade werden die Widget-Eigenschaften normalerweise während der Bearbeitung fest eingestellt. Sie können jedoch Widgeteigenschaften zur Laufzeit festlegen, z.B. anhand von INI-Dateiwerten, was normalerweise im Initialisierungscode des Handlers geschieht. Das Setzen von Eigenschaften aus HAL-Pin-Werten ist ebenfalls möglich.

Im folgenden Beispiel (unter der Annahme eines HAL Meter-Widgets mit dem Namen meter) wird der Minimalwert des Zählers beim Start über einen INI-Dateiparameter und der Maximalwert über einen HAL-Pin eingestellt, wodurch die Skala des Widgets dynamisch angepasst wird:

import linuxcnc
import os
import hal
import hal_glib

class HandlerClass:

    def _on_max_value_change(self,hal_pin,data=None):
        self.meter.max = float(hal_pin.get())
        self.meter.queue_draw() # force a widget redraw

    def __init__(self, halcomp,builder,useropts):
        self.builder = builder

        # HAL-Pin mit Änderungs-Callback.
        # Wenn sich der Wert des Pins ändert, wird der Callback ausgeführt.
        self.max_value = hal_glib.GPin(halcomp.newpin('max-value',  hal.HAL_FLOAT, hal.HAL_IN))
        self.max_value.connect('value-changed', self._on_max_value_change)

        inifile = linuxcnc.ini(os.getenv("INI_FILE_NAME"))
        mmin = float(inifile.find("METER", "MIN") or 0.0)
        self.meter = self.builder.get_object('meter')
        self.meter.min = mmin


def get_handlers(halcomp,builder,useropts):
    return [HandlerClass(halcomp,builder,useropts)]

8.17. "Wert hat sich geändert"-Callback Funktion mit hal_glib

GladeVCP nutzt die hal_glib-Bibliothek, die dazu verwendet werden kann, ein "watcher" Signal an einen HAL-Eingangspin anzuschließen.
Dieses Signal kann verwendet werden, um eine Funktion zu registrieren, die aufgerufen wird, wenn sich der Zustand des HAL-Pins ändert.

Man muss das hal_glib und das hal-Modul importieren:

import hal_glib
import hal

Erstellen Sie dann einen Pin und verbinden Sie ein value-changed Signal (den Watcher) mit einem Funktionsaufruf:

class HandlerClass:
    def __init__(self, halcomp,builder,useropts):
        self.example_trigger = hal_glib.GPin(halcomp.newpin('example-trigger', hal.HAL_BIT, hal.HAL_IN))
        self.example_trigger.connect('value-changed', self._on_example_trigger_change)

Und eine Funktion haben, die aufgerufen werden soll:

    def _on_example_trigger_change(self,pin,userdata=None):
        print("pin value changed to: {}".format(pin.get()))
        print("pin name= {}".format(pin.get_name()))
        print("pin type= {}".format(pin.get_type()))

        # dies kann außerhalb der Funktion aufgerufen werden
        self.example_trigger.get()

8.18. Beispiele und die Entwicklung Ihrer eigenen GladeVCP-Anwendung

Besuchen Sie linuxcnc_root_directory/configs/apps/gladevcp für laufende Beispiele und Startprogramme für Ihre eigenen Projekte.

9. FAQ

  1. Ich erhalte ein unerwartetes Unmap-Ereignis in meiner Handler-Funktion direkt nach dem Start. Was ist das?

    Dies ist eine Folge davon, dass in Ihrer Glade UI-Datei die Eigenschaft window1 Visible auf True gesetzt ist und das GladeVCP-Fenster in AXIS oder touchy neu geparentet wird. Der GladeVCP-Widget-Baum wird erstellt, einschließlich eines Fensters der obersten Ebene, und dann in AXIS "reparented", so dass das Fenster der obersten Ebene verwaist herumliegt. Um zu vermeiden, dass dieses nutzlose leere Fenster herumhängt, wird es entmappt (unsichtbar gemacht), was die Ursache für das Unmap-Signal ist, das Sie erhalten. Vorgeschlagene Lösung: window1.visible auf False setzen und ein anfängliches Unmap-Ereignis ignorieren.

  2. Mein GladeVCP-Programm startet, aber es erscheint kein Fenster dort, wo ich es erwarte?

    Das Fenster, das AXIS für GladeVCP zuweist, erhält die "natürliche Größe" aller seiner untergeordneten Widgets zusammen. Es ist die Aufgabe der untergeordneten Widgets, eine Größe (Breite und/oder Höhe) anzufordern. Allerdings fordern nicht alle Widgets eine Breite größer als 0 an, zum Beispiel das Graph-Widget in seiner aktuellen Form. Wenn es ein solches Widget in Ihrer Glade-Datei gibt und es dasjenige ist, welches das Layout definiert, sollten Sie seine Breite explizit festlegen. Beachten Sie, dass das Festlegen der Eigenschaften Breite und Höhe von window1 in Glade nicht sinnvoll ist, da dieses Fenster beim Re-Parenting verwaist wird und seine Geometrie daher keine Auswirkungen auf das Layout hat (siehe oben). Generell gilt: Wenn Sie eine UI-Datei manuell mit gladevcp <uifile> ausführen und ihr Fenster eine vernünftige Geometrie hat, sollte es auch in AXIS korrekt angezeigt werden.

  3. Ich möchte eine blinkende LED, aber sie blinkt nicht

    Ich habe das Kontrollkästchen aktiviert, damit die Anzeige im Abstand von 100 ms blinkt. Sie blinkt nicht, und ich erhalte eine Startwarnung: Warning: value "0" of type ‚gint‘ is invalid or out of range for property ‚led-blink-rate‘ of type ‚gint‘? Dies scheint ein Glade-Bug zu sein. Überschreiben Sie einfach das Feld für die Blinkrate und speichern Sie erneut - das funktioniert bei mir.

  4. Mein GladeVCP-Panel in AXIS speichert den Status nicht, wenn ich AXIS schließe, obwohl ich einen on_destroy-Handler definiert habe, der mit dem Fensterzerstörungssignal verbunden ist

    Sehr wahrscheinlich ist dieser Handler mit window1 verknüpft, das aufgrund des Reparenting für diesen Zweck nicht verwendbar ist. Bitte verknüpfen Sie den on_destroy-Handler mit dem destroy-Signal eines inneren Fensters. Ich habe z.B. ein Notizbuch innerhalb von window1 und habe on_destroy mit dem Zerstörungssignal des Notizbuchs verknüpft, und das funktioniert gut. Für window1 funktioniert es nicht.

  5. Ich möchte die Hintergrundfarbe oder den Text eines HAL_Label-Widgets abhängig von seinem HAL-Pin-Wert einstellen

    Siehe das Beispiel in configs/apps/gladevcp/colored-label. Das Einstellen der Hintergrundfarbe eines GtkLabel-Widgets (und HAL_Label ist von GtkLabel abgeleitet) ist ein wenig knifflig. Das GtkLabel-Widget hat aus Leistungsgründen kein eigenes Fensterobjekt, und nur Fensterobjekte können eine Hintergrundfarbe haben. Die Lösung ist, das Label in einen EventBox-Container einzuschließen, der ein Fenster hat, aber ansonsten unsichtbar ist - siehe die Datei coloredlabel.ui.

Ich habe ein "hal_spinbutton"-Widget in Glade definiert und eine Standard-Eigenschaft value in der entsprechenden Einstellung festgelegt. Wieso zeigt es Null?

Dies ist auf einen Fehler in der alten Gtk-Version zurückzuführen, die mit Ubuntu 8.04 und 10.04 verteilt wird, und ist wahrscheinlich der Fall für alle Widgets, die Anpassung verwenden. Der Workaround, der zum Beispiel in http://osdir.com/ml/gtk-app-devel-list/2010-04/msg00129.html erwähnt wird, setzt den HAL-Pin-Wert nicht zuverlässig, es ist besser, ihn explizit in einem on_realize-Signal-Handler während der Widget-Erstellung zu setzen. Siehe das Beispiel in configs/apps/gladevcp/by-widget/spinbutton.{ui,py}.

10. Fehlersuche

  • Stellen Sie sicher, dass Sie die Entwicklungsversion von LinuxCNC installiert haben. Sie brauchen nicht die axisrc Datei nicht mehr, wurde dies in der alten GladeVCP Wiki-Seite erwähnt.

  • Starten Sie GladeVCP oder AXIS in einem Terminalfenster. Wenn Sie Python-Fehler erhalten, prüfen Sie, ob neben der neueren /usr/lib/python2.6/dist-packages/_hal.so Datei noch eine /usr/lib/python2.6/dist-packages/_hal.so Datei herumliegt (den Unterstrich beachten); wenn ja, entfernen Sie die hal.so Datei. Sie wurde durch hal.py im selben Verzeichnis ersetzt und verwirrt den Importmechanismus.

  • Wenn Sie run-in-place verwenden, führen Sie ein make clean aus, um alle versehentlich übrig gebliebenen hal.so-Dateien zu entfernen, und dann make.

  • Wenn Sie die Widgets HAL_table oder HAL_HBox verwenden, beachten Sie bitte, dass sie einen HAL-Pin haben, der standardmäßig ausgeschaltet ist. Dieser Pin steuert, ob die Kinder dieser Container aktiv sind oder nicht.

11. Implementierungshinweis: Schlüsselbehandlung in AXIS

Wir glauben, dass die Handhabung der Tasten gut funktioniert, aber da es sich um neuen Code handelt, informieren wir Sie darüber, damit Sie auf Probleme achten können; bitte teilen Sie uns Fehler oder seltsames Verhalten mit. Dies ist die Geschichte:

AXIS verwendet den TkInter-Widgetsatz. GladeVCP-Anwendungen verwenden Gtk-Widgets und werden in einem separaten Prozesskontext ausgeführt. Sie werden über das Xembed-Protokoll in AXIS eingebunden. Dies ermöglicht es einer untergeordneten Anwendung wie GladeVCP, sich ordnungsgemäß in ein übergeordnetes Fenster einzufügen und - theoretisch - eine integrierte Ereignisbehandlung zu haben.

Dies setzt jedoch voraus, dass sowohl die übergeordnete als auch die untergeordnete Anwendung das Xembed-Protokoll korrekt unterstützen, was bei Gtk der Fall ist, bei TkInter jedoch nicht. Eine Folge davon ist, dass bestimmte Tasten von einem GladeVCP-Panel nicht unter allen Umständen korrekt an AXIS weitergeleitet werden können. Eine dieser Situationen war der Fall, wenn ein Entry- oder SpinButton-Widget den Fokus hatte: In diesem Fall wurde z.B. eine Escape-Taste nicht an AXIS weitergeleitet und führte zu einem Abbruch, wie es sein sollte, mit möglicherweise katastrophalen Folgen.

Daher werden Tastenereignisse in GladeVCP explizit behandelt und selektiv an AXIS weitergeleitet, um sicherzustellen, dass solche Situationen nicht auftreten können. Für Details siehe die Funktion keyboard_forward() in lib/python/gladevcp/xembed.py.

12. Hinzufügen von benutzerdefinierten Widgets

Das LinuxCNC Wiki hat Informationen über das Hinzufügen von benutzerdefinierten Widgets zu GladeVCP. GladeVCP Custom Widgets

13. GladeVCP-Hilfsanwendungen

Es werden unabhängig installierte GladeVCP-Anwendungen unterstützt, die mit der Platzierung des Systemverzeichnisses übereinstimmen, wie sie von den LINUXCNC_AUX_GLADEVCP- und LINUXCNC_AUX_EXAMPLES-Elementen definiert wird, die vom Skript linuxcnc_var gemeldet werden:

$ linuxcnc_var LINUXCNC_AUX_GLADEVCP
/usr/share/linuxcnc/aux_gladevcp
$ linuxcnc_var LINUXCNC_AUX_EXAMPLES
/usr/share/linuxcnc/aux_examples

Das durch LINUXCNC_AUX_GLADEVCP definierte Systemverzeichnis (/usr/share/linuxcnc/aux_gladevcp) gibt den Speicherort für eine GladeVCP-kompatible Python-Datei(en) und zugehörige Unterverzeichnisse an. Die Python-Datei wird beim Start von GladeVCP importiert und für nachfolgende GladeVCP-Anwendungen verfügbar gemacht, einschließlich der eingebetteten Verwendung in unterstützenden GUIs.

Das durch LINUXCNC_AUX_EXAMPLES definierte Systemverzeichnis (/usr/share/linuxcnc/aux_examples) gibt den Speicherort von Beispielkonfigurations-Unterverzeichnissen an, die für Hilfsanwendungen verwendet werden. Siehe den Abschnitt getting-started/running-linuxcnc für Hinzufügen von Konfigurationsauswahlen.

Zu Testzwecken kann mit der exportierten Umgebungsvariablen eine Laufzeitspezifikation von Hilfsanwendungen angegeben werden: GLADEVCP_EXTRAS. Diese Variable sollte eine Pfadliste von einem oder mehreren Konfigurationsverzeichnissen sein, die durch ein (:) getrennt sind. Normalerweise wird diese Variable in einer Shell gesetzt, die linuxcnc startet, oder im ~/.profile Startskript eines Benutzers. Beispiel:

export GLADEVCP_EXTRAS=~/mygladevcp:/opt/othergladevcp

Dateien, die in Verzeichnissen gefunden werden, die mit der Umgebungsvariablen GLADEVCP_EXTRAS angegeben sind, ersetzen gleichnamige Dateien in Unterverzeichnissen des durch LINUXNC_AUX_GLADEVCP angegebenen Systemverzeichnisses (z. B. /usr/share/linuxcnc/aux_gladevcp). Diese Bestimmung ermöglicht es einem Entwickler, eine Anwendung zu testen, indem er GLADEVCP_EXTRAS exportiert, um ein privates Anwendungsverzeichnis anzugeben, ohne ein im System installiertes Anwendungsverzeichnis zu entfernen. Meldungen über abgelehnte Duplikate werden auf stdout ausgegeben.

Anmerkung

Die Unterstützung für GladeVCP-Hilfsanwendungen erfordert ein Python-Modul namens importlib. Dieses Modul ist möglicherweise in älteren Installationen wie Ubuntu-Lucid nicht verfügbar.