WICHTIG: Der Betrieb von goMatlab.de wird privat finanziert fortgesetzt. - Mehr Infos...

Mein MATLAB Forum - goMatlab.de

Mein MATLAB Forum

 
Gast > Registrieren       Autologin?   

Partner:




Forum
      Option
[Erweitert]
  • Diese Seite per Mail weiterempfehlen
     


Gehe zu:  
Neues Thema eröffnen Neue Antwort erstellen

rekursiver Aufruf einer subgui

 

DSP
Forum-Meister

Forum-Meister



Beiträge: 2.117
Anmeldedatum: 28.02.11
Wohnort: ---
Version: R2014b
     Beitrag Verfasst am: 30.01.2016, 10:07     Titel: rekursiver Aufruf einer subgui
  Antworten mit Zitat      
Hallo goMatlab Forum,

ich habe eine MainGUI u.a. mit 2 Pushbuttons, welche dieselbe Callback Funktion haben in der eine subgui aufgerufen wird. Die MainGUI ist zur Darstellung von 1 oder 2 Signalen und die Buttons für die Maximum und Minimum Peaks der Signale/des Signals.

Man drückt nun z.B. den Button Maximum Peaks und ruft damit die subgui auf. Die Peaks werden im Plotfenster dargestellt und die subgui zeigt in einer Tabelle die Peakwerte an (siehe Bild). Nun drückt der User den Button für die Minimum Peaks. D.h. die subgui wird erneut aufgerufen, während sie von dem ersten Call noch geöffnet ist. Somit werden nun auch die Min. Peaks sowohl im Plot als auch in der Tabelle der subgui angezeigt. Mein Problem liegt nun in der Durchführung der beiden Calls bzw. eigentlich mit der Weiterführung des 1. Calls nachdem der 2. Call beendet wurde.

Gibt es die Möglichkeit den 1. Call während des 2. Call zu beenden?

Vielen Dank schon mal für eure Hilfe!

Gruß DSP

SignalViewer.png
 Beschreibung:

Download
 Dateiname:  SignalViewer.png
 Dateigröße:  410.46 KB
 Heruntergeladen:  501 mal
Private Nachricht senden Benutzer-Profile anzeigen


Harald
Forum-Meister

Forum-Meister


Beiträge: 24.495
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 30.01.2016, 10:57     Titel:
  Antworten mit Zitat      
Hallo,

was genau meinst du mit "beenden"? Die Subgui schließen?
Wenn du beim Aufruf ein Handle auf die Subgui zurückholst und in der Hauptgui speicherst, kannst du die eine eventuell existierende Instanz von Subgui mit close oder delete schließen. ishandle ist hilfreich, um zu testen, ob die Subgui zuvor schon manuell geschlossen wurden.

Grüße,
Harald
Private Nachricht senden Benutzer-Profile anzeigen
 
DSP
Themenstarter

Forum-Meister

Forum-Meister



Beiträge: 2.117
Anmeldedatum: 28.02.11
Wohnort: ---
Version: R2014b
     Beitrag Verfasst am: 30.01.2016, 11:36     Titel:
  Antworten mit Zitat      
Es gibt ja bei der Bedienung 2 Möglichkeiten zum Beenden der GUI. Entweder schließe ich die GUI über das x oder der Button.state = off. Sprich ich drück den Button Maxpaks zum Einschalten = 1. Call und Button.state = on. Nun drücke ich den Button nochmal zum Beenden = 2. Call und Button.state = off.

In diesem Fall werden zwar die Peaks im Plot gelöscht, aber die GUI bleibt immer noch offen.

Zitat:
Wenn du beim Aufruf ein Handle auf die Subgui zurückholst und in der Hauptgui speicherst, kannst du die eine eventuell existierende Instanz von Subgui mit close oder delete schließen. ishandle ist hilfreich, um zu testen, ob die Subgui zuvor schon manuell geschlossen wurden.


Ich kann den 2. Call nicht schließen, während der 1. Call in uiwait status hängt. Das geht zwar, aber komme ich dann zurück in den 1. Call ist von der subgui nichts mehr vorhanden. Ich erhalte dann folgenden Fehler:

Code:
Error using matlab.ui.Figure/set
Invalid or deleted object.

Error in PeaksTable (line 214)
    set(handles.GUIPeaksTable,'Position',handles.PeaksTablePos)

Error in SignalViewer/FindPeaksItem_Callback (line 4220)
            PeaksTable(handles.graph, handles.Data.hLineS,...
 
Error using waitfor
Error while evaluating ToggleTool ClickedCallback


Ich habe hier mal den Ablauf der subgui soweit gekürzt, so dass es nur um die Zustände subgui start, restart und close geht. Evtl. siehst du ja wo mein Fehler ist. Die Daten der subgui speichere ich im figure handle meiner Maingui.

Code:

function PeaksTable(axh, hLineS, hMainGUI, MinPeakDist, MinPeakHeight, PeaksNum, MaxPeaksState, MinPeaksState)

if isempty(findall(0,'type','figure','Tag','GUIPeaksTable'))

    handles.GUIPeaksTable = figure(...
    'Name','Tabelle Max-/MinPeaks',...
    'HandleVisibility','on',...
    'Tag','GUIPeaksTable',...
    'CloseRequestFcn',{@close_GUI});

    % here come more subgui objects...


    % empty graphic place holder
    handles.hLineMaxPeaksS = gobjects(1,2);
    handles.hLineMinPeaksS = gobjects(1,2);    
   
    handles.hLinePeak = gobjects(1);
    handles.hTextLabel = gobjects(1);
else
    % GUI is already running because of previous call
    %close(findall(0,'type','figure','name','Tabelle Max-/MinPeaks'))
   
    % get subGUI data
    handles = getappdata(hMainGUI,'hPeaksTable');
             
    % delete data cursor in plot if available
    if ishghandle(handles.hLinePeak)
        delete(handles.hLinePeak)
        delete(handles.hTextLabel)
    end
   
    % set former position
    set(handles.GUIPeaksTable,'Position',handles.PeaksTablePos)
   
    % Peaks table on top of Signalviewer    
    figure(handles.GUIPeaksTable)
   
    % Update handles structure
    guidata(gcbo, handles);
end

%% get Peaks and plot them ---------------------------------------------------------------
% ...
% ----------------------------------------------------------------------------------------  

if (sum(ishghandle(handles.hLineMaxPeaksS)) > 0) || (sum(ishghandle(handles.hLineMinPeaksS)) > 0)
    % grafic handle available
    % show Max and/or Minpeaks in table
else
    % NO peaks available -> grafic handle empty
    % save subgui data in MainGUI
    setappdata(hMainGUI,'hPeaksTable',handles)
    % close GUI
    %close_GUI
end



% get current gui position
handles.PeaksTablePos = get(handles.GUIPeaksTable,'Position');

% Update handles structure
guidata(gcbo, handles);

% save subgui data in MainGUI
setappdata(hMainGUI,'hPeaksTable',handles)

% UIWAIT makes GUI wait for user response (see UIRESUME)
uiwait(handles.GUIPeaksTable);
                       
                       
%% Callbacks -----------------------------------------------------------------------------

    function close_GUI(varargin)
        try
            handles = getappdata(hMainGUI,'hPeaksTable');

            % delete data cursor in plot            
            delete(findall(0,'type','line','Tag','PeakMarker'))
            delete(findall(0,'Tag','PeakLabel'))
           
            % get current gui position
            handles.PeaksTablePos = get(handles.GUIPeaksTable,'Position');            

            for m = 1:sum(ishghandle(handles.hLineMaxPeaksS))
                % delete max peaks in existing plot            
                delete(handles.hLineMaxPeaksS(m));
                delete(findall(0,'type','line','tag',['hLineMinPeaksS' num2str(m)]))
                handles.hLineMaxPeaksS(m) = gobjects(1);
            end            
           
            for m = 1:sum(ishghandle(handles.hLineMinPeaksS))
                % delete min peaks in existing plot            
                delete(handles.hLineMinPeaksS(m));
                delete(findall(0,'type','line','tag',['hLineMinPeaksS' num2str(m)]))
                handles.hLineMinPeaksS(m) = gobjects(1);
            end      
           
            % save the changes to the structure
            guidata(gcbo,handles);

            % save subgui data in MainGUI
            setappdata(hMainGUI,'hPeaksTable',handles)
            % close GUI
            delete(handles.GUIPeaksTable)

        catch
            handles = getappdata(hMainGUI,'hPeaksTable');
            % close GUI
            delete(handles.GUIPeaksTable)
        end
    end
end
 
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.495
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 30.01.2016, 17:24     Titel:
  Antworten mit Zitat      
Hallo,

mir ist noch nicht klar, welches Verhalten du genau erreichen möchtest.
Im Zusammenhang mit uiwait gibt es uiresume, um quasi das uiwait aufzuheben.

Grüße,
Harald
Private Nachricht senden Benutzer-Profile anzeigen
 
DSP
Themenstarter

Forum-Meister

Forum-Meister



Beiträge: 2.117
Anmeldedatum: 28.02.11
Wohnort: ---
Version: R2014b
     Beitrag Verfasst am: 30.01.2016, 18:57     Titel:
  Antworten mit Zitat      
Ich gehe mal von einem Signal aus und es erfolgt folgender Ablauf

1. Button MaxPeaks on = von User gedrückt
- Plot MaxPeaks und zeige MaxPeak-Werte in Tabelle
1. Call der subgui

2. Button MinPeaks on
- Plot Max und MinPeaks und zeige Peakwerte in Tabelle
2. Call der subgui -> 1. Call ist noch aktiv wegen uiwait

entweder

3a. subgui wird geschlossen (x angeklickt)
- schließe die subgui und lösche existierte Peaks im Plot -> ENDE

oder

3b. Button MinPeaks off
- lösche die Minpeaks im Plot und in der Tabelle und zeige nur die MaxPeaks

4. Button MaxPeaks off
- schließe die subgui und lösche die MaxPeaks im Plot -> ENDE


Mein Problem ist der noch offne 1.Call, während ein 2. Call gerade beendet wurde. Daher fragte ich auch, ob man im 2. Call den 1. Call einfach beenden kann. close oder delete schließen nur den aktuellen call und logischerweise wird dann der vorhergehende Call bei Rekursion weitergeführt.


Ich habe nun zwar den Ablauf wie gewünscht hinbekommen. aber nachdem die CloseRequestFcn @close_GUI ausgeführt wurde, ist der 2. Call beendet und nun lande ich wieder beim 1. Call und habe wieder folgender Fehler, da die figure in der close Funktion ja schon gelöscht wurde.

Code:

Error using uiwait (line 48)
Input argument must be of type figure

Error in PeaksTable (line 402)
uiwait(handles.GUIPeaksTable);

Error in SignalViewer/FindPeaksItem_Callback (line 4215)
        PeaksTable(handles.graph, handles.Data.hLineS,...
 
Error using waitfor
Error while evaluating ToggleTool ClickedCallback
 


Ich habe es auch mit einem uiresume(handles.GUIPeaksTable) in der Close Fcn versucht, was aber nichts bewirkt.

Aber vermutlich wirst du auch mit dieser Beschreibung deine Probleme haben sie nachzuvollziehen. Das Projekt ist mittlerweile schon recht groß, weshalb es mir schwer fällt diese Thematik auf ein eigenes lauffähiges Bsp. zu bringen. Ich kann dir natürlich das Projekt geben...aber dann brauchst du auch eine Anleitung, was wie zu bedienen ist und wo breakpoints zu setzen sind. Ist halt auch nicht ideal.

Dennoch vielen Dank für deine Bemühung mir zu helfen.
Private Nachricht senden Benutzer-Profile anzeigen
 
DSP
Themenstarter

Forum-Meister

Forum-Meister



Beiträge: 2.117
Anmeldedatum: 28.02.11
Wohnort: ---
Version: R2014b
     Beitrag Verfasst am: 30.01.2016, 19:11     Titel:
  Antworten mit Zitat      
Ich habe jetzt noch einen Versuch ohne das uiwait(subgui) gemacht. Damit erreiche ich ja, dass nach der Abarbeitung des Codes in der subgui, wieder in die Callback der MainGUI gesprungen wird.

Ich habe damit den gewünschten Ablauf herstellen können. Bis auf eine Sache...klickt man das x zum Schließen der subgui an, springt er nicht mehr in die Callback der MainGUI zurück? Warum nicht?

Wenn ich nämlich die subgui darüber schließe, bleibt der Button state auf on, wenn er zuvor gedrückt wurde. Da ich dann nicht mehr in der Callback der Maingui zu dem Button lande, kann ich auch den state nicht auf off setzen.

Die Peaks und die subgui sind zwar weg, aber ein oder beide Button(s) ist/sind an Evil or Very Mad
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.495
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 30.01.2016, 19:20     Titel:
  Antworten mit Zitat      
Hallo,

Zitat:
Bis auf eine Sache...klickt man das x zum Schließen der subgui an, springt er nicht mehr in die Callback der MainGUI zurück? Warum nicht?

An sich muss der schon zu Ende ausgeführt worden sein.

Zitat:
Wenn ich nämlich die subgui darüber schließe, bleibt der Button state auf on, wenn er zuvor gedrückt wurde.

Könnte man das in der CloseRequestFcn der Subgui ändern?

Grüße,
Harald
Private Nachricht senden Benutzer-Profile anzeigen
 
DSP
Themenstarter

Forum-Meister

Forum-Meister



Beiträge: 2.117
Anmeldedatum: 28.02.11
Wohnort: ---
Version: R2014b
     Beitrag Verfasst am: 30.01.2016, 20:58     Titel:
  Antworten mit Zitat      
Hallo,

klar...du hast Recht! Der Code in der subgui wurde ja durchgeführt, dann zurück in den Callback der MainGUI. Dort wird noch Code abgefragt aber nicht ausgefüht und die Callback wird verlassen. Erst dann drückt man auf x und die subgui wird geschlossen.

Sicherlich ist es kein Problem die Buttons in der subgui auszuschalten. Aber das ist schon irgendwie von hinten durch die Brust ins Auge. Es muss doch auch einen Weg über uiwait in der subgui geben. Dann ist auch das Umschalten der Button states kein Problem. Oder man nutzt eine Togglebutton, der nach dem Betätigen sofort wieder auf off geht. Dann sieht man aber an Hand der Buttons nicht, welche Peaks an sind. Was ich auch nicht verstehe, ist die Sache mit den geplotten Peaks. Werden Min- und MaxPeaks angezeigt, wurde die subgui 2 mal aufgerufen. Die Peaks vom 1+2.Call können mit

Code:

% Line Handles der Peaks löschen
delete(handles.hLineMaxPeaksS)
delete(handles.hLineMinPeaksS)
 


entfernt werden. Sind beide Peaks an und werden nacheinander durch beide Buttons entfernt wird die subgui am Ende geschlossen. Also also ok. Sind beide Peaks an, aber die subgui wird durch x beendet, werden immer die Max- oder MinPeaks, die im 1. Call aufgerufen wurden, nicht gelöscht. Obwohl die line handles beider Peaks in der close function vorhanden sind.

Dann können beide Peaks nur über findobj gelöscht werden.

Code:

            % delete Max Peaks
            for m = 1:sum(ishghandle(handles.hLineMaxPeaksS))
                % delete max peaks in existing plot            
                delete(findobj(0,'type','line','tag',['hLineMaxPeaksS' num2str(m)]))
                handles.hLineMaxPeaksS(m) = gobjects(1);
            end
 


Warum?

Gruß DSP
Private Nachricht senden Benutzer-Profile anzeigen
 
DSP
Themenstarter

Forum-Meister

Forum-Meister



Beiträge: 2.117
Anmeldedatum: 28.02.11
Wohnort: ---
Version: R2014b
     Beitrag Verfasst am: 06.02.2016, 13:29     Titel:
  Antworten mit Zitat      
Ich weiß nun warum das Löschen des handles aus dem ersten Call nicht mehr direkt über das Objekt handle geht.

Im 1. Call wird ja entweder Min oder Max Peaks angeklickt und somit das 1. Objekt handle erzeugt. Beim 2 Call sind nun Min und Max Peaks ausgewählt und somit werden die Objekt handles für beide Peaks neu erzeugt. Dadurch sind diese beiden handles andere als das handle aus dem 1. Call.

Der Zugriff auf das Objekt handle aus dem 1. Call ist somit nur über findobj zu realisieren.

Ich müsste daher immer gleich beide Peaks erzeugen und nur jenen sichtbar machen, der gerade ausgewählt wird. Dann könnte ich mit den handles arbeiten. Da dieser Programmablauf aber andere Probleme mit sich bringt, bleibt es bei der Umsetzung mit findobj.

Gruß DSP
Private Nachricht senden Benutzer-Profile anzeigen
 
Neues Thema eröffnen Neue Antwort erstellen



Einstellungen und Berechtigungen
Beiträge der letzten Zeit anzeigen:

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 | goMatlab RSS Button RSS

Hosted by:


Copyright © 2007 - 2024 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.