|
|
Speichern und Laden von GUIs |
|
Lisbeth Salander |
Gast
|
|
Beiträge: ---
|
|
|
|
Anmeldedatum: ---
|
|
|
|
Wohnort: ---
|
|
|
|
Version: ---
|
|
|
|
|
|
Verfasst am: 26.07.2012, 10:38
Titel: Speichern und Laden von GUIs
|
|
Hallo!
Ich programmiere gerade eine GUI, in der verschiedene Werte über Edit-Felder eingelesen und gespeichert werden sollen (in den handles und im Workspace). Nun möchte ich eine GUI mit eingetragenen Werten speichern, sie schließen und eine GUI (mit der gleichen Oberfläche) neu öffnen und mir über die load-Funktion die Werte meiner vorherigen GUI laden. Ist das möglich? Ich habe es bereits geschafft, die handles über ein .mat-File zu speichern und zu laden, aber ich hätte auch gerne die Einträge meiner Edit-Felder und die Variablen im Workspace wieder in meiner neuen GUI. Muss ich das neu über die handles eintragen oder kann man dies evtl. auch direkt bei einer GUI speichern und laden?
Vielen Dank schon im voraus für Antworten
|
|
|
|
|
flashpixx |
Forum-Guru
|
|
Beiträge: 355
|
|
|
|
Anmeldedatum: 19.04.08
|
|
|
|
Wohnort: ---
|
|
|
|
Version: ---
|
|
|
|
|
|
Verfasst am: 26.07.2012, 11:24
Titel:
|
|
Ich verstehe das jetzt nicht so ganz, aber wenn man fest Werte an GUI aus einer anderen übergeben will, setzt man diese entsprechend in den Handles und übergibt diesen bei Erzeugung der neuen GUI.
Wenn es feste Werte sind, die immer existieren sollen, dann kann man diese in der GUI (via guide) auch direkt im entsprechenden GUI Element speichern
|
|
|
Harald |
Forum-Meister
|
|
Beiträge: 24.495
|
|
|
|
Anmeldedatum: 26.03.09
|
|
|
|
Wohnort: Nähe München
|
|
|
|
Version: ab 2017b
|
|
|
|
|
|
Verfasst am: 26.07.2012, 12:07
Titel:
|
|
Hallo,
das wird etwas aufwändiger - zumindest wüsste ich nicht, wie es einfacher geht.
Man müsste von jedem einzelnen GUI-Element die relevanten (= veränderlichen) Informationen abfragen und diese in einer .mat-Datei speichern.
Beispiel:
Beim Laden müsste umgekehrt jedem einzelnen GUI-Element diese relevanten Informationen wieder zugewiesen werden.
Grüße,
Harald
|
|
|
flashpixx |
Forum-Guru
|
|
Beiträge: 355
|
|
|
|
Anmeldedatum: 19.04.08
|
|
|
|
Wohnort: ---
|
|
|
|
Version: ---
|
|
|
|
|
|
Verfasst am: 26.07.2012, 13:42
Titel:
|
|
Eigentlich müssten die GUI Objekte so eine Methode "onOpen" bzw "onClose" haben bzw. allgemein bei Objekten kann die "delete" Methode (Destruktor) überladen werden analog der Konstruktor.
Damit müsste sich das Laden / Speichern recht gut realisieren lassen. D.h. in den Konstruktor das erzeugen der GUI hinein, die dann die Daten aus der Datei einliest und beim in "delete" das Speichern hinein.
|
|
|
Lisbeth Salander |
Gast
|
|
Beiträge: ---
|
|
|
|
Anmeldedatum: ---
|
|
|
|
Wohnort: ---
|
|
|
|
Version: ---
|
|
|
|
|
|
Verfasst am: 26.07.2012, 15:22
Titel:
|
|
Hallo,
vielen Dank schonmal für die vielen Antworten... Die onOpen und onClose-Funktion kenne ich nicht, allerdings soll die GUI auch nicht immer dabei geschlossen oder neu erzeugt werden, es sollen nur Werte (und damit auch Inhalte der Edit-Felder) gespeichert und geladen werden können..
Ich hatte befürchtet, dass es nur auf die aufwändige Art, wie Harald sie beschreibt, funktioniert
Wäre es denn richtig, alle strings in ein .mat-File mit folgendem Befehl zu speichern:
Ich habe gerade das Problem, verschiedenen Strings in meinen save-Befehl reinzupacken, weil vllt nicht jeder Benutzer alle Edit-Felder ausfüllt..
Ich würde zunächst mit dem isfield-Befehl überprüfen, ob ein handle vorhanden ist, aber wie bekomme ich dann genau die Variablen, die existieren, in die Form
?
Wäre toll, wenn mir jemand helfen könnte, ich stehe gerade auf dem Schlauch!
|
|
|
flashpixx |
Forum-Guru
|
|
Beiträge: 355
|
|
|
|
Anmeldedatum: 19.04.08
|
|
|
|
Wohnort: ---
|
|
|
|
Version: ---
|
|
|
|
|
|
Verfasst am: 26.07.2012, 19:43
Titel:
|
|
Lisbeth Salander hat Folgendes geschrieben: |
vielen Dank schonmal für die vielen Antworten... Die onOpen und onClose-Funktion kenne ich nicht, allerdings soll die GUI auch nicht immer dabei geschlossen oder neu erzeugt werden, es sollen nur Werte (und damit auch Inhalte der Edit-Felder) gespeichert und geladen werden können.. |
Es gibt keine "onClose" bzw "onOpen" Methode, es geht nur um das Konzept !
Mein Tipp schreibe Deine GUI ohne guide, dazu findest Du mehrere Threads hier im Forum, als Klasse. In der Klasse implementierst Du dann eine Methode "save" bzw "load", in der Du dann passend zu Deiner GUI das Laden und Speichern der Daten übernimmst. Ob Du da jetzt ein mat, csv oder xml File nimmst, sei dann Dir überlassen. Aber mit Hilfe dieser Methoden kannst Du dann ganz flexibel Deine Daten verwenden.
|
|
|
Harald |
Forum-Meister
|
|
Beiträge: 24.495
|
|
|
|
Anmeldedatum: 26.03.09
|
|
|
|
Wohnort: Nähe München
|
|
|
|
Version: ab 2017b
|
|
|
|
|
|
Verfasst am: 26.07.2012, 21:04
Titel:
|
|
Hallo,
du musst wie gesagt die Eigenschaften auslesen. Die Handles-Struktur an sich wird dir später wenig helfen, weil es ja die referenzierten Objekte nicht mehr gibt.
Ob eine Eingabe erfolgt ist oder nicht, ist meiner Meinung nach egal. Wenn es keine Eingabe gab, ist der String halt leer.
Die Frage ist, wie gut man im Programmieren ist. Für einen durchschnittlichen Nutzer halte ich objektorientierte Ansätze hier für überzogen.
Für Nutzer ohne große Programmierkenntnisse ist das Erzeugen der GUI mit GUIDE oft einfacher und intuitiver.
Grüße,
Harald
|
|
|
flashpixx |
Forum-Guru
|
|
Beiträge: 355
|
|
|
|
Anmeldedatum: 19.04.08
|
|
|
|
Wohnort: ---
|
|
|
|
Version: ---
|
|
|
|
|
|
Verfasst am: 27.07.2012, 06:31
Titel:
|
|
|
|
|
Harald hat Folgendes geschrieben: |
Für einen durchschnittlichen Nutzer halte ich objektorientierte Ansätze hier für überzogen. |
OOP ist heute Stand der aktuellen Technik, nur weil das eben anscheinend in Matlab noch nicht als gängiges Paradigma umgesetzt wird, heißt es nicht, dass es überzogen ist.
Meines Wissens gibt es mit Hilfe einer guide erstellten GUI keine Möglichkeit fest zu stellen, ob die GUI noch im Speicher liegt, denn es existiert keine Callfunktion, die aufgerufen wird, wenn die GUI geschlossen wird. Also fehlt bei einem rein prozeduralen Ansatz die Möglichkeit aus der GUI fest zu stellen, ob sie noch existent ist, sofern man nicht ggf im Workspace o.ä. eine entsprechende Variable hinterlegt, was aber aufgrund des Softwaredesignkonzeptes völlig mangelhaft wäre, denn eine externe Variable kann ich jeder Zeit manipulieren.
Eine GUI ist, auch wenn es vielleicht in Matlab anders aussieht, letztendlich vollständig javabasiert und beruht letztendlich auf dem OOP Konzept. Lediglich die Ansteuerung über Matlab ist eher prozedural gehalten, unten drunter ist es aber OOP. Warum soll man sich als verbiegen und irgendwie prozeduralen Code zusammen frickeln, anstatt direkt das zu der GUI passende Paradigma zu verwenden.
Erstelle ich die GUI per Hand innerhalb einer Klasse, dann kann ich mein GUI Element beliebig oft verwenden, jede Instanz der Klasse ist unabhängig, zusätzlich habe ich definierte Schnittstellen, an die ich wiederum andere Elemente anhängen kann. Gehe ich noch einen Schritt weiter, dann kann ich z.B. eine klassische Event-Listener-Struktur aufbauen:
Damit kann würde dann beim "clear all", die Funktion doOnClose aufgerufen und das eben für alle myGUI() Instanzen (sofern die Funktion bei jedem Objekt registiert wurde). OOP ist nicht schwerer als ein prozeduraler Ansatz auch, bietet aber durch die Kapselung weit mehr Möglichkeiten als ein prozeduraler Ansatz.
Harald hat Folgendes geschrieben: |
Für Nutzer ohne große Programmierkenntnisse ist das Erzeugen der GUI mit GUIDE oft einfacher und intuitiver.
|
Das ist sicherlich richtig, mit guide kann man schnell per Klick die GUI erzeugen, muss aber auch mit den Einschränkungen leben. Eine per guide erstelle GUI ist letztendlich auch OOP, denn die GUI Elemente sind OOP Strukturen, die Callbackfunktionen werden an einem Event-Interface registriert und wenn ich dann z.B. auf einen Buttonclicke, wird für jedes Element in der Interfaceliste die Matlab Callback Funktion mit den Parametern aufgerufen. Das ist letztendlich exakt das gleiche Prinzip, das ich oben im Beispielcode gezeigt habe. Der Unterschied besteht lediglich darin, dass ich einmal den Code selbst entwerfen bzw. mir einmal selbst Gedanken machen muss.
Im Grunde lässt sich aber das hier gestellte Problem relativ einfach umsetzen:
Damit wäre gesichert, dass beim Aufruf des Konstruktors die GUI Daten geladen werden, d.h. bei Darstellung der GUI vorhanden sind und beim release der GUI Variablen geschrieben werden, da der Destruktor deterministisch aufgerufen wird. Jede GUI ist unabhängig von den anderen, d.h. hier muss man das beim Laden / Speichern berücksichtigen, soll die GUI nur ein einziges Mal existieren kann man dies im Konstruktor mit Hilfe von findobj fest stellen und passend darauf reagieren.
|
|
|
Harald |
Forum-Meister
|
|
Beiträge: 24.495
|
|
|
|
Anmeldedatum: 26.03.09
|
|
|
|
Wohnort: Nähe München
|
|
|
|
Version: ab 2017b
|
|
|
|
|
|
Verfasst am: 27.07.2012, 08:21
Titel:
|
|
|
|
|
Hallo flashpixx,
Zitat: |
nur weil das eben anscheinend in Matlab noch nicht als gängiges Paradigma umgesetzt wird |
Was meinst du damit? Die Möglichkeiten dazu sind in MATLAB doch vorhanden; man wird nur nicht gezwungen, (explizit) objektorientiert zu arbeiten.
Zitat: |
Meines Wissens gibt es mit Hilfe einer guide erstellten GUI keine Möglichkeit fest zu stellen, ob die GUI noch im Speicher liegt, denn es existiert keine Callfunktion, die aufgerufen wird, wenn die GUI geschlossen wird. |
In der OpeningFcn könnte man folgenden Code platzieren:
Ich möchte dir in keiner Weise widersprechen, was den Stand der Technik etc. angeht; man darf nur eines nicht vergessen:
Ein großer Teil der MATLAB-Nutzer (ich habe das vorhin als "durchschnittlicher Nutzer" bezeichnet; das ist im übrigen nicht abfällig gemeint) sieht sich nicht als Programmierer in dem Sinn, sondern möchte lediglich seine benötigten Anwendungen erstellen. Die meisten dieser Nutzer haben keine Kenntnisse von OOP und auch kein Interesse daran, sich darin einzuarbeiten. Für diese Leute bestünde das Verbiegen darin, wenn man sie zwingen würde, objektorientiert zu arbeiten.
Ich sehe es also so, dass OOP ein guter Ansatz für größere, komplexere Projekte ist. Eine (relativ einfache) GUI zählt für mich nicht dazu.
Zudem: das eigentliche Problem, wie die Daten nun gespeichert und geladen werden, ist ja durch dein Gerüst noch nicht gelöst?
Grüße,
Harald
|
|
|
flashpixx |
Forum-Guru
|
|
Beiträge: 355
|
|
|
|
Anmeldedatum: 19.04.08
|
|
|
|
Wohnort: ---
|
|
|
|
Version: ---
|
|
|
|
|
|
Verfasst am: 27.07.2012, 12:22
Titel:
|
|
|
|
|
Harald hat Folgendes geschrieben: |
Was meinst du damit? Die Möglichkeiten dazu sind in MATLAB doch vorhanden; man wird nur nicht gezwungen, (explizit) objektorientiert zu arbeiten.
|
Ja, ist doch genauso in C++, ich kann C Code in C++ einbetten.
Harald hat Folgendes geschrieben: |
In der OpeningFcn könnte man folgenden Code platzieren:
|
Stimmt, hatte ich nach dem Schreiben meines Postings in der Hilfe gesehen
Harald hat Folgendes geschrieben: |
Ein großer Teil der MATLAB-Nutzer (ich habe das vorhin als "durchschnittlicher Nutzer" bezeichnet; das ist im übrigen nicht abfällig gemeint) sieht sich nicht als Programmierer in dem Sinn, sondern möchte lediglich seine benötigten Anwendungen erstellen. Die meisten dieser Nutzer haben keine Kenntnisse von OOP und auch kein Interesse daran, sich darin einzuarbeiten.
|
Ich würde dann zu diesem Punkt die Frage stellen, wie kann man sich dann sicher sein, dass der Code den man "irgendwie" entwickelt etwas definiertes berechnet und vor allem das korrekte Ergebnis liefert !? Ob man nun OOP verwendet oder prozedural arbeitet, den Code muss man verstehen.
Harald hat Folgendes geschrieben: |
Ich sehe es also so, dass OOP ein guter Ansatz für größere, komplexere Projekte ist. Eine (relativ einfache) GUI zählt für mich nicht dazu.
|
In Java würde dies gar nicht gehen, in Windows wie in den .NET Sprachen auch nicht. Auch bei kleinen Projekten macht OOP durchaus Sinn, denn meist beginnt mit einem kleinen Projekt ein größeres und gerade bei Matlab existieren häufig "gewachsene" Strukturen und oft müsste man Refactoring des Codes machen. Ich sehe das somit auch bei kleinen Projekten einen sinnvollen Einsatz der OOP und gerade hier würde es sich doch anbieten.
Nehme ich noch das "CloseRequestFcn" in den OOP Ansatz hinzu, dann kann ich durch den Konstruktor die Daten laden lassen, die GUI selbst ist ein in sich abgeschlossenes Objekt und sobald das Objekt released wird, kann ich die Daten schreiben, das ist absolut konsistent. Gibt man z.B. über den Konstruktor den Namen der GUI mit, kann man mehrere GUIs des gleichen Typs mit unterschiedlichen Parametern laden / speichern. Durch die Klassenstruktur in Matlab habe ich dann auch alles immer an einem Ort auf der Festplatte liegen, d.h. Klasse, GUI und auch ggf Speicherstand, wenn er zentral gehalten werden soll. Ansonsten lege ich den Speicherstand in das Homeverzeichnis des Users und initialisiere wenn dort keine Datei liegt mit Defaultwerten. Damit hätte ich dann eine extrem flexible GUI, die ich dann bequem auch überall verwenden kann.
Harald hat Folgendes geschrieben: |
Zudem: das eigentliche Problem, wie die Daten nun gespeichert und geladen werden, ist ja durch dein Gerüst noch nicht gelöst?
|
Das "wie" kann man sich doch überlegen, XML Datei, CSV Datei, MAT Datei mit Struct oder Map, HDF Datei oder auch Datenbank. Ich bin davon ausgegangen, dass ich den Zugriff auf die Properties der GUI Objekte als bekannt voraussetzen kann, ebenso wie entsprechender Dateizugriff. Du hattest dies ja im groben schon in Deinem ersten Posting verdeutlicht. Ich würde einen Struct / Map nehmen bzw. wenn es flexibler sein soll, dann wohl ein XML und dann für jede GUI bzw. GUI Element einen Eintrag mit den gewünschten Daten hinterlegen. Bei XML wäre würde ich folgende Struktur verwenden
In gleicher Form kann man auch Struct oder Map aufbauen (bei XML kann man dann auch noch theoretisch via XSD die Semantik des Dokumentes prüfen und die Datenkonvetierung wird auch direkt vorgenommen). Benötigt man mehrere Eigenschaften der GUI Objekte kann man das dann noch beliebig tiefer strukturieren. CSV wäre etwas umständlicher, deshalb würde ich dies nicht nehmen.
|
|
|
Harald |
Forum-Meister
|
|
Beiträge: 24.495
|
|
|
|
Anmeldedatum: 26.03.09
|
|
|
|
Wohnort: Nähe München
|
|
|
|
Version: ab 2017b
|
|
|
|
|
|
Verfasst am: 27.07.2012, 13:10
Titel:
|
|
|
|
|
Hallo,
Zitat: |
Harald hat Folgendes geschrieben:
Was meinst du damit? Die Möglichkeiten dazu sind in MATLAB doch vorhanden; man wird nur nicht gezwungen, (explizit) objektorientiert zu arbeiten.
Ja, ist doch genauso in C++, ich kann C Code in C++ einbetten. |
Das bestreite ich auch gar nicht. Mich hat lediglich die Aussage "nur weil das eben anscheinend in Matlab noch nicht als gängiges Paradigma umgesetzt wird" irritiert.
Zitat: |
Ich würde dann zu diesem Punkt die Frage stellen, wie kann man sich dann sicher sein, dass der Code den man "irgendwie" entwickelt etwas definiertes berechnet und vor allem das korrekte Ergebnis liefert !? Ob man nun OOP verwendet oder prozedural arbeitet, den Code muss man verstehen. |
Natürlich sollte man den Code verstehen. "sollte", weil es wohl genug Leute gibt, die lediglich darauf Wert legen, dass der Code [soweit ersichtlich] das tut, was er soll. Eine Garantie, dass der Code das macht, was er soll, bekommt man bei OOP genausowenig.
Zitat: |
In Java würde dies gar nicht gehen, in Windows wie in den .NET Sprachen auch nicht. |
Ich hätte vielleicht klarstellen sollen, dass es mir ausschließlich um OOP in MATLAB geht.
Grüße,
Harald
|
|
|
flashpixx |
Forum-Guru
|
|
Beiträge: 355
|
|
|
|
Anmeldedatum: 19.04.08
|
|
|
|
Wohnort: ---
|
|
|
|
Version: ---
|
|
|
|
|
|
Verfasst am: 27.07.2012, 13:48
Titel:
|
|
|
|
|
Harald hat Folgendes geschrieben: |
Mich hat lediglich die Aussage "nur weil das eben anscheinend in Matlab noch nicht als gängiges Paradigma umgesetzt wird" irritiert.
|
Ich nutze einige freie Toolboxen ein und keine davon ist OOP und gerade bei GUI, die ja schon technisch OOP ist, ist es halt für mich unverständlich, warum man da dann doch immer wieder
ein prozedurales Muster zurück fällt. Ich finde das eher hinderlich, weil man kann sich doch in diesem Fall viel Arbeit sparen, wenn man es hübsch kapselt und dann verwendet.
Harald hat Folgendes geschrieben: |
Natürlich sollte man den Code verstehen. "sollte", weil es wohl genug Leute gibt, die lediglich darauf Wert legen, dass der Code [soweit ersichtlich] das tut, was er soll. Eine Garantie, dass der Code das macht, was er soll, bekommt man bei OOP genausowenig.
|
Natürlich, ich bin mit Dir da auch einer Meinung und ich weiß auch was Du meinst.
@topic: Ich denke halt in diesem Bsp wäre OOP angebracht, ich würde im Konstruktor die Daten aus der Datei in eon Objektproperty laden bzw. wenn die Datei nicht vorhanden ist Defaultwerte setzen. Dann die GUI mit den Objektwerte erzeugen (oder falls man es braucht eine eigene show-Methode dafür bauen) und die Handels in einem Property ablegen. Beim Schließen über die "CloseRequestFcn" Callback Funktion die Daten in ein Objektproperty ablegen und falls man dann via Methode die GUI noch einmal aufmacht einfach direkt dort die Daten nehmen und die GUI neu initialisieren.
Im Konstruktor würde ich eben den Zugriff auf eine Source (Datei / Datenbank) setzen, der mir die Einstellungen des Objektes liest und im Destruktor schreibt. Damit kann ich sicher sein, dass meine Werte immer konsistent da sind, wenn die GUI öffnet und ebenso wenn das Objekt out-of-scope geht, der Destruktor das Speichern übernimmt (lässt sich natürlich auch über eigene Methoden realisieren). Die Callbacks der GUI rufe ich dann einfach als Klassenmethoden auf.
Ich denke zur konkreten Implementation muss man sich dann anhand der Verwendung einige Gedanken machen, aber ich denke so wäre das ganze aus meiner Sicht sinnvoll gekapselt und auch klar strukturiert. Es ist halt deterministisch definiert wann die Daten gelesen und geschrieben werden (dies kommt aus dem Multithreading, da ich hier ja noch ggf einen Mutex haben muss, da keine zwei Thread schreibend auf die gleiche Resource drauf zugreifen dürfen). Wenn man es sich dann einfach machen möchte würde ich einfach die Daten in ein Struct und MAT-File ablegen und das dann an einen definierten Ort ablegen.
|
|
|
Marco H. |
Forum-Guru
|
|
Beiträge: 404
|
|
|
|
Anmeldedatum: 12.11.10
|
|
|
|
Wohnort: Dortmund
|
|
|
|
Version: 2010a/2012b
|
|
|
|
|
|
Verfasst am: 27.07.2012, 16:03
Titel:
|
|
Hey,
@Lisbeth Salander: Wenn du es ganz einfach haben möchtest, dann kannste es ggf. auch mit hgsave und hgload machen. Da sind natütlich die Möglichkeiten bergenzt aber vll reichts ja.
Ansonsten würde ich mich meinen Vorrednern anschließen, entweder wie Harald es sagt alle Objekte auslesen und Abspeichern dann beim Laden wieder Objecte entsprechend setzen oder die fürn Anfnag sehr herreusfordernde Möglichkeit via OOP...
Greetings
|
|
|
flashpixx |
Forum-Guru
|
|
Beiträge: 355
|
|
|
|
Anmeldedatum: 19.04.08
|
|
|
|
Wohnort: ---
|
|
|
|
Version: ---
|
|
|
|
|
|
Verfasst am: 27.07.2012, 18:13
Titel:
|
|
|
|
Marco H. |
Forum-Guru
|
|
Beiträge: 404
|
|
|
|
Anmeldedatum: 12.11.10
|
|
|
|
Wohnort: Dortmund
|
|
|
|
Version: 2010a/2012b
|
|
|
|
|
|
Verfasst am: 28.07.2012, 13:55
Titel:
|
|
Natürlich ist das nicht die optimale Lösung. Für quick an dirty aber ausreichend...
Greetings
|
|
|
|
|
Einstellungen und Berechtigungen
|
|
Du kannst Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen. Du kannst Dateien in diesem Forum posten Du kannst Dateien in diesem Forum herunterladen
|
|
Impressum
| Nutzungsbedingungen
| Datenschutz
| FAQ
| RSS
Hosted by:
Copyright © 2007 - 2025
goMatlab.de | Dies ist keine offizielle Website der Firma The Mathworks
MATLAB, Simulink, Stateflow, Handle Graphics, Real-Time Workshop, SimBiology, SimHydraulics, SimEvents, and xPC TargetBox are registered trademarks and The MathWorks, the L-shaped membrane logo, and Embedded MATLAB are trademarks of The MathWorks, Inc.
|
|