LabVIEWForum.de - Events in anderen VIs aufrufen

LabVIEWForum.de

Normale Version: Events in anderen VIs aufrufen
Du siehst gerade eine vereinfachte Darstellung unserer Inhalte. Normale Ansicht mit richtiger Formatierung.
Hallo,

ich würde gern einen Großteil meiner Knöpfe und Anzeigen vom Frontpanel in ein kleines Fenster packen, welches immer im Vordergrund ist, aber dafür beweglich und evt. auch minimierbar.
Also kurz: So etwas wie das Funktions- oder Tools-Fenster in LabVIEW nachprogrammieren.

Ich will aber die zugehörigen Events, die die jeweiligen Aktionen der Knöpfe auswerten in meinem Main-VI lassen. Die Frage lautet nun, wie kann ich möglichst ohne grossen Aufwand und ohne viel in der Programmstruktur zu ändern, diese Knöpfe in ein anderes Fenster bringen?

Ich stelle mir das in etwa so vor:
Ich kopiere die Knöpfe in das neue Fenster und erstelle dort die typischen Eventcases. Diese Eventcases rufen nun die original Eventcases aus dem Main-VI auf.
Geht sowas?

Ich weiß, das es in LV sogenannte dynamisch registrierte/erstellte Events gibt, habe davon aber keine Ahnung.
Brauche ich diese denn?
Deine Konzeption finde ich gut, die gesamte Bedienung in ein gesondertes VI zu packen, und gut ist auch die Ereignissteuerung in diesem VI. Ich nenne das mal "Server-VI", Das andere wäre dann das ist "Client-VI"
Deine eigentliche Frage kann ich Dir mangels Wissen nicht beantworten, ich kann Dir nur sagen, wie ich von da ab weiter vorgehen würde - ohne Gewähr, daß es optimal ist.

Im Falle eines Ereignisses im Server-VI ist dreierlei an das Client-VI zu übermitteln:
a) die Tatsache, daß überhaupt ein Ereignis stattgefunden hat
b) Welches Bedienelement betätigt wurde
c) Der neue Wert des Elements

Ich würde den Austausch mit Melden vornehmen (eg wird an diese Stelle sofort dazwischenrufen "Nein, Queue benutzen wegen Datenverlust")

zu a) Der Melder wartet auf der Empfangsseite normalerweise, bis neue Daten ankommen. Das würde den Ablauf des VI blockieren. Entweder sollte Timeout=0 sein und man macht Polling, oder man generiert ein dynamisches Ereignis bei Eintreffen von Daten (Dynamisch gezwungenermaßen, weil die normalen Ereignisse immer Bedienereignisse sind, was hier nicht der Fall ist)

Zu b) und c) Der Melder kann natürlich die Informationen gleich enthalten, also Beschriftung und Wert. Das Ganze wird etwas kompliziert, wenn es sich um ganz verschiedene Bedienelemente-Typen handelt, aber es ist machbar, z.B über die Konvertierung in Variant. (oder einfacher: gesonderte Melder für jeden Datentyp verwenden) Aber prinzipiell wären da auch andere "Vertriebswege" denkbar, notfalls sogar mit globalen Variablen oder mit funktionalen Globalen Variablen. Mit Referenzen geht es meines Erachtens nicht.

Das Einfachste wäre natürlich, wenn man bei jedem Ereignis über den Melder einen ganzen Cluster mit allen Werten an das Client-VI übergibt, auf dem sich der gleiche Cluster mit den "Schattenwerten" des Server-VIs befindet.
Hallo,

ich muss sowas über Netzwerk machen und verwende dafür "Shared Variables". Ich nehme dabei boolsche SV's zum Synchronisieren und andere SV's zur Datenübergabe.
Dabei habe ich im Client-VI und im Server-VI jeweils eine Statemachine, in der in den diversen Cases die boolschen SV gesetzt werden.

Kleines Bsp.: Der Client-Rechner will einen Messwert abholen. Dazu schreibt er den Messbefehl in eine SV. Danach wird eine boolsche SV auf True gesetzt, welche dann auf dem Server-Rechner in den Case weiterschaltet, wo der vorhin geschriebene Messbefehl abgeholt und verarbeitet wird. Der auf dem Server erfasste Messwert wird in eine andere SV geschrieben. Nachdem dies geschehen ist, wird eine weitere boolsche SV auf True gesetzt, welche in der Statemachine des Clients die Abholung des Messwerts hervorruft.
Das ist also ein Zusammenspiel zwischen mehreren boolschen Synchronisations- und Daten-SV's. Du musst dabei halt immer die boolschen SV's zurücksetzen und dann im entsprechenden Case der Statemachine auf die weiteren Aktionen warten.
Dabei kannst Du ja mehrere Server-VIs parallel laufen lassen.

Gruß Markus

' schrieb:Hallo,

ich würde gern einen Großteil meiner Knöpfe und Anzeigen vom Frontpanel in ein kleines Fenster packen, welches immer im Vordergrund ist, aber dafür beweglich und evt. auch minimierbar.
Also kurz: So etwas wie das Funktions- oder Tools-Fenster in LabVIEW nachprogrammieren.

Ich will aber die zugehörigen Events, die die jeweiligen Aktionen der Knöpfe auswerten in meinem Main-VI lassen. Die Frage lautet nun, wie kann ich möglichst ohne grossen Aufwand und ohne viel in der Programmstruktur zu ändern, diese Knöpfe in ein anderes Fenster bringen?

Ich stelle mir das in etwa so vor:
Ich kopiere die Knöpfe in das neue Fenster und erstelle dort die typischen Eventcases. Diese Eventcases rufen nun die original Eventcases aus dem Main-VI auf.
Geht sowas?

Ich weiß, das es in LV sogenannte dynamisch registrierte/erstellte Events gibt, habe davon aber keine Ahnung.
Brauche ich diese denn?
' schrieb:Ich weiß, das es in LV sogenannte dynamisch registrierte/erstellte Events gibt, habe davon aber keine Ahnung.
Brauche ich diese denn?

Es ist eine Möglichkeit aber ich denke in diesem Fall etwas Overkill, sicher wenn Du planst um jedem Button ein eigenes dynamisches Event zuzuordnen. Selber würde ich das mit Queues implementieren und falls Du Locking nötig hast um zu verhindern dass weitere Buttons gedrückt werden bevor der erste abgearbeitet ist, noch einen Return Notifier verwenden der Deinem VI sagt dass das Element abgeholt und verarbeitet wurde.

Eventuel könntest Du auch ein dynamisches Event benützen um anzugeben dass irgendein Button geklickt wurde und die Information über den Button als Daten an das Event mitgeben.

Rolf Kalbermatter
' schrieb:Es ist eine Möglichkeit aber ich denke in diesem Fall etwas Overkill, sicher wenn Du planst um jedem Button ein eigenes dynamisches Event zuzuordnen. Selber würde ich das mit Queues implementieren und falls Du Locking nötig hast um zu verhindern dass weitere Buttons gedrückt werden bevor der erste abgearbeitet ist, noch einen Return Notifier verwenden der Deinem VI sagt dass das Element abgeholt und verarbeitet wurde.

Eventuel könntest Du auch ein dynamisches Event benützen um anzugeben dass irgendein Button geklickt wurde und die Information über den Button als Daten an das Event mitgeben.

Rolf Kalbermatter
Ich würde die Frage etwas anders beantworten und hatte das im Beitrag weiter oben bereits versucht. Mit dynamischen Ereignisse kann man zwei Dinge machen, die mit normalen Ereignissen nicht zu machen sind:

1.) Dynamische Ereignisse lassen sich erst während des Programmablaufes aktivieren und deaktivieren. Die normalen Ereignisse sind während der ganzen Progammdauer scharf geschalten.

2) Die Bezeichnung "Ereignis" für ein normales Ereignis ist fast irreführend. Es ist nämlich in Wirklichkeit fast
nichts was passiert ein "Ereignis", sondern nur etwas ganz Spezielles: Das sind manuelle Operationen an Bedienelementen. (Ausnahme: Wertzuweisung über Eigenschaft Wert-signalisierend)
Mit dynamischen Ereignissen ist das hingegen anders: Man kann fast alles was im Programm passiert, als dynamisches Ereignis registrieren. (z.B das Eintreffen neuer Daten bei der Datenerfassung)

Für Dich bedeutet das:
a) Server-VI: Es gibt nicht den geringsten Grund, die Bedienelement-Ereignisse dynamisch zu machen, da es sich (i) eben um Bedienereignisse handelt, die keiner dynamischen Registrierung bedürfen und (ii) die Ereignisse während der ganzen Programmdauer scharf geschalten sein sollen.

b) Client-VI: Das Eintreffen neuer Daten, z.B über die Queue, ist kein (Bedien)ereignis. Wenn man also darauf besteht, dieses Eintreffen als Ereignis zu verarbeiten, muß es dynamisch registriert werden. (Man kann das u.U. umgehen, indem man dem "SchattenCluster" mit den Bedienleementen auf dem Client-VI die neuen Werte über die Eigenschaft "Wert, signalisierend" zuweist.)
Also erstmal vielen Dank für die Antworten.
Scheinbar ist die Lösung doch nicht so einfach wie ich dachte.
Auch wenn ich nicht alle Details eurer Antworten verstanden habe, so habe ich zumindest ein Beispiel gefunden, in dem Ereignisse (+Daten) mittels Queues von einem VI aufs andere VI übertragen werden. Wahrscheinlich werde ich mich daran orientieren.

Ich hoffte nur anfangs, man könnte evt. den Code im Client - VI unverändert lassen, und einfach nur die Event-Cases vom Server-VI aus aufrufen.

So ähnlich wie man in Delphi den Event "Form1.Button1.click" von jeder beliebigen Stelle der Anwendung (auch aus anderen Formularen heraus) aufrufen kann. Das hat nämlich den Vorteil, das ich die Prozedur "Form1.Button1.click" nicht umschreiben muss.
Zum Thema habe ich was gebastelt. Die zwei VIs kommunizieren miteinander über dynamische User Events. Genauso gut kann man Queues verwenden.

Wichtig: beide VIs sind im Beispiel gleichwertig, also nix mit Server und Client. Beide VIs sind Server und Client gleichzeitig.

Analog dazu kann man tausende von SubVIs einfügen, die kreuz und quer miteinander kommunizieren, Events austauschen, Daten übertragen (z.B. von einer Schnittstelle gesammelten Daten). Nach diesem Prinzip sind die meisten meiner Projekte aufgebaut.

Mit dem Unterschied:
Ich benutze gemischte Kommunikation aus allen möglichen Übertragungsmedien wie Events, Queues, Notifiers. Allerdings benutze ich NIE VARIABLEN.

Ich erzeuge einen Cluster aus Arrays auf die Referenzen auf die Übertragungsmedien mit For-Schleifen, da diese immer vom gleichen Typ "String" sind. Für Referenzen schliessen gilt das gleiche. Den erzeugten Cluster bekommen ALLE Module (VIs) als Eingang, somit hat jedes VI die Möglichkeit mit jedem anderen VI zu kommunizieren.

Ich arbeite mit Enum Typedefs um die Quelle und Ziel aus dem Array auszuwählen.

Ansonsten ist alles ziemlich ähnlich wie im Beispiel.

Gruss, eg
Referenz-URLs