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

Callback uimenu, update handles

 

sputnik644
Forum-Newbie

Forum-Newbie


Beiträge: 7
Anmeldedatum: 02.01.16
Wohnort: ---
Version: R2016b
     Beitrag Verfasst am: 02.01.2016, 15:58     Titel: Callback uimenu, update handles
  Antworten mit Zitat      
Geschätzte Forumsteilnehmer

Mit folgendem Code wird ein Kontextmenü erzeugt:
Code:

item1 = uimenu(inouthandles.ContextMenu(i),...
   'Checked','on',...
   'Label','test',...
   'Callback',{@ContextMenuAction,handles,val});
 



soweit ok.
Die aufgerufene Fuktion lautet:

Code:

function ContextMenuAction(hObject,callbackdata,inhandles,inVal)
       
        %Position 1
        delete(inhandles.item(inVal));
        %................................................
        % die folgende Linie erzeugt einen Plot in einer bestehenden Figur
        [inhandles]=NewPlot(hObject,inhandles,inVal)
        %................................................
        %Position 2
        delete(inhandles.item(inVal));
end
 




Der Befehl delete(inhandles.item(inVal)) löscht den in der Funktion erzeugten Plot wieder.

Steht der Befehl an Position 2 ist alles ok und der soeben erzeugte Plot wird bei jedem Aufruf gelöscht.

Steht der Befehl jedoch an Position 1 (d.h. löschen des beim letzten Aufruf erzeugten Plots), so wird der Plot nicht gelöscht, keine Fehlermeldung, die Evaluation des Befehls ergibt "handle to deleted Graphics".
inhandles scheint den neuen Plot nicht aus der Funktion exportieren zu können.
Wie kann erreicht werden, dass der delete Befehl in Position 1 erfolgreich ausgeführt wird?

Besten Dank und Grüsse
sputnik644
Private Nachricht senden Benutzer-Profile anzeigen


DSP
Forum-Meister

Forum-Meister



Beiträge: 2.117
Anmeldedatum: 28.02.11
Wohnort: ---
Version: R2014b
     Beitrag Verfasst am: 02.01.2016, 16:09     Titel:
  Antworten mit Zitat      
Hallo,

ich bin mir nicht sicher, ob ich dein Bsp. richtig verstanden habe. Aber die Daten in einem Plot kann man auch so löschen:

Code:
% reset plot
    cla(axes_object,'reset')
Private Nachricht senden Benutzer-Profile anzeigen
 
sputnik644
Themenstarter

Forum-Newbie

Forum-Newbie


Beiträge: 7
Anmeldedatum: 02.01.16
Wohnort: ---
Version: R2016b
     Beitrag Verfasst am: 02.01.2016, 16:21     Titel:
  Antworten mit Zitat      
Hallo

Es soll nur die vorher erzeugte Linie/Kurve gelöscht werden und nicht das ganze Axes Objekt. Der delete Befehl ist nicht so sehr relevant, es geht darum, dass eine in einem Callback Aufruf erzeugte Linie in einem Plot im nächsten Callback Aufruf nicht mehr erkannt wird.

Grüsse
sputnik644
Private Nachricht senden Benutzer-Profile anzeigen
 
DSP
Forum-Meister

Forum-Meister



Beiträge: 2.117
Anmeldedatum: 28.02.11
Wohnort: ---
Version: R2014b
     Beitrag Verfasst am: 02.01.2016, 16:45     Titel:
  Antworten mit Zitat      
Dann wäre es wohl für die Helfenden sinnvoll zu wissen, wie du den Plot und deren Objekte erstellst.

Evtl. hilft folgendes Bsp.

Code:
figure(1)
ax = gca;
t = 0:pi/20:2*pi;
% sinus kurve
hline(1) = plot(ax,t,sin(t),'k');
% linie
hline(2) = line([0 1],[0.2 0.2],'LineWidth',4,...
   'Color',[.8 .8 .8],...
   'Parent',ax);

set(ax,'Children',hline)

pause(5)

delete(hline(1))


Andere Frage: Speicherst du denn Änderungen in deinem Handle in den Funktionen auch ab? In deinem Code ist es nicht vorhanden, wie so etwas z.B.

Code:
% save the changes to the structure
        guidata(gcbo,handles);
Private Nachricht senden Benutzer-Profile anzeigen
 
sputnik644
Themenstarter

Forum-Newbie

Forum-Newbie


Beiträge: 7
Anmeldedatum: 02.01.16
Wohnort: ---
Version: R2016b
     Beitrag Verfasst am: 02.01.2016, 17:11     Titel:
  Antworten mit Zitat      
Hallo

Danke für die Hinweise, der Plot wird z.b. mit
plot(x,sin(x)) erstellt.
Das Problem ist, dass der in der Funktion erzeugte Plot
mit F9 inhandles.item(inVal)) korrekt als Linie erkannt wird, beim nächsten Aufruf
bringt F9 inhandles.item(inVal)) nur noch "handle to deleted Graphics".
Die Funktion wird nach dem ersten Aufruf ja wieder verlassen und dabei geht etwas verloren.
Bei Funktionen kann ich output Argumente definieren [varargout]=myfunc(varargin); da funktioniert auch alles bestens. Bei Callback im uimenu kann man jedoch keine output Argumente definieren.
Es muss doch sonst eine Möglichkeit geben, die in einem Callback erzeugten Objekte auch ausserhalb der Callback Funktion oder eben beim nächsten Aufruf zur Verfügung zu haben zum löschen/ändern etc.
Private Nachricht senden Benutzer-Profile anzeigen
 
DSP
Forum-Meister

Forum-Meister



Beiträge: 2.117
Anmeldedatum: 28.02.11
Wohnort: ---
Version: R2014b
     Beitrag Verfasst am: 02.01.2016, 17:51     Titel:
  Antworten mit Zitat      
Wie gesagt...deine kompletter Code würde deutlich mehr helfen. Außerdem scheint es mir, dass ich mit meinem Hinweise zum Abspeichern von Änderungen des Handles innerhalb einer Callbackfunktion nicht ganz falsch liege Wink

Ich würde mir mal in der Doku den Befehl guidata oder hier im Forum genauer ansehen. Ansonsten gibt es z.B. auch folgende Möglichkeit handles zu erstellen und in Callbacks zugreifen.

Code:

function [] = testgui()

handles.MainWindow = figure('PaperUnits','inches',...
'Units','normalized',...
'Position',[1 1 0.2 0.2],...
'Visible',get(0,'defaultfigureVisible'),...
'Color',get(0,'defaultfigureColor'),...
'CurrentAxesMode','manual',...
'IntegerHandle','off',...
'MenuBar','none',...
'ChildrenMode','manual',...
'ParentMode','manual',...
'HandleVisibility','on',...
'CreateFcn', {@movegui,'center'});

handles.Button = uicontrol(...
'Parent',handles.MainWindow,...
'Units','normalized',...
'String','Drück mich',...
'Enable','on',...
'Style','pushbutton',...
'Position',[0.1 0.25 0.2 0.2],...
'ForegroundColor',[0 0 0],...
'Callback',{@Button_Callback});

handles.Textfield = uicontrol(...
'Parent',handles.MainWindow,...
'Units','normalized',...
'String','',...
'Style','text',...
'Position',[0.5 0.25 0.2 0.5],...
'ForegroundColor',[0 0 0],...
'Callback',{});

% add some additional data to handle

handles.MyData = {'hallo'};

set(handles.Textfield,'String',handles.MyData)

% Update handles structure
guidata(handles.MainWindow, handles);

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


% Callback

function Button_Callback(varargin)
     handles.MyData = {'tschö'};
     set(handles.Textfield,'String',handles.MyData)
end
end
 
Private Nachricht senden Benutzer-Profile anzeigen
 
sputnik644
Themenstarter

Forum-Newbie

Forum-Newbie


Beiträge: 7
Anmeldedatum: 02.01.16
Wohnort: ---
Version: R2016b
     Beitrag Verfasst am: 02.01.2016, 18:53     Titel:
  Antworten mit Zitat      
Hallo

eben ein Stück Code:

Code:
function ContextMenuAction(hObject,callbackdata,inhandles)
% Wird beim Wechsel eines Kontextmenus ausgeführt
       
% Position 1: nachfolgender delete Befehl wird nicht ausgeführt
delete(inhandles.item(1));

t=linspace(0,pi);
inhandles.item(1)=plot(t,sin(t));

% Position 2: nachfolgender delete Befehl wird ausgeführt
delete(inhandles.item(1));

guidata(gcbo,inouthandles);

end


das Kontextmenu wird in einer anderen Funktion erstellt:

Code:
item1 = uimenu(handles.ContextMenu(1),...
   'Checked','on',...
   'Label','test',...
   'Callback',{@ContextMenuAction,handles});


Nun sollte es etwas klarer sein. Beim wiederholten Aufrufen der Callbackfunktion wird der im vorangehenden Aufruf erzeugte Plot inhandles.item(1) nicht gelöscht, wenn der delete Befehl in der Position 1 gesetzt ist.
Private Nachricht senden Benutzer-Profile anzeigen
 
DSP
Forum-Meister

Forum-Meister



Beiträge: 2.117
Anmeldedatum: 28.02.11
Wohnort: ---
Version: R2014b
     Beitrag Verfasst am: 02.01.2016, 19:16     Titel:
  Antworten mit Zitat      
Ehrlich gsagt ist es nicht karer. Für mich ist hier widersprüchlich...

'Callback',{@ContextMenuAction,handles});

function ContextMenuAction(hObject,callbackdata,inhandles)

guidata(gcbo,inouthandles);


3 verschiedene handles. Wie soll das gehen? Also entweder postest du mal ein lauffähiges Bsp. oder ich kann dir leider nicht weiterhelfen.
Private Nachricht senden Benutzer-Profile anzeigen
 
sputnik644
Themenstarter

Forum-Newbie

Forum-Newbie


Beiträge: 7
Anmeldedatum: 02.01.16
Wohnort: ---
Version: R2016b
     Beitrag Verfasst am: 02.01.2016, 19:26     Titel:
  Antworten mit Zitat      
sorry war ein Fehler mit den handles:

Code:
function ContextMenuAction(hObject,callbackdata,handles)
% Wird beim Wechsel eines Kontextmenus ausgeführt
       
% Position 1: nachfolgender delete Befehl wird nicht ausgeführt
delete(handles.item(1));

t=linspace(0,pi);
handles.item(1)=plot(t,sin(t));

% Position 2: nachfolgender delete Befehl wird ausgeführt
delete(handles.item(1));

guidata(gcbo,handles);

end


und

Code:
item1 = uimenu(handles.ContextMenu(1),...
   'Checked','on',...
   'Label','test',...
   'Callback',{@ContextMenuAction,handles});



Es funktioniert trotzdem nicht.
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: 02.01.2016, 19:43     Titel:
  Antworten mit Zitat      
Hallo,

wie ist handles.item denn initialisiert?
Mit dem momentanen Code löscht du das Objekt direkt nach seiner Erzeugung, und beim nächsten Aufruf des Callbacks nochmal. Dass es dann nicht mehr gelöscht werden kann, ist naheliegend, denn es ist ja schon gelöscht.

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

Forum-Newbie

Forum-Newbie


Beiträge: 7
Anmeldedatum: 02.01.16
Wohnort: ---
Version: R2016b
     Beitrag Verfasst am: 03.01.2016, 08:17     Titel:
  Antworten mit Zitat      
Guten Tag Harald

Besten Dank für den Hinweis mit der Initialisierung von handles.item. Ich habe das Problem wie folgt erfolgreich gelöst:

2 neue Funktionen (gem. Hilfe):

Code:
function setGlobal(handles)

global x
x = handles;

end


und

Code:
function handles=getGlobal

global x
handles = x;

end


Nach dem Erzeugen der Kontextmenüs
Code:
item1 = uimenu(handles.ContextMenu(1),...
   'Checked','on',...
   'Label','test',...
   'Callback',{@ContextMenuAction,handles});


zusätzlich:

Code:
setGlobal(handles);


In der Callback Funktion selber:

Code:
function ContextMenuAction(hObject,callbackdata,handles)
% Wird beim Wechsel eines Kontextmenus ausgeführt

% zusätzlich*************************************
handles=retGlobal;
% *********************************************

% Position 1: nachfolgender delete Befehl wird nicht ausgeführt
delete(handles.item(1));

t=linspace(0,pi);
handles.item(1)=plot(t,sin(t));

% Position 2: nachfolgender delete Befehl wird ausgeführt
delete(handles.item(1));


guidata(gcbo,handles);
% zusätzlich*************************************
setGlobal(handles);
% *********************************************

end


So funktioniert es wie ich es mir vorstelle. Es gibt vielleicht elegantere Methoden dies zu erreichen. Globale Variablen sollte man ja "sehr sparsam" benutzen.
Besten Dank und Grüsse
sputnik644
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: 03.01.2016, 10:35     Titel:
  Antworten mit Zitat      
Hallo,

wozu denn die schreckliche Krücke mit globalen Variablen?! Viel "Spaß", wenn du das dann noch jemals debuggen musst...

Inzwischen ist mir klar, wo das Problem liegt: du übergibst jedes Mal dieselbe Handles-Variable an den Callback, das Update hilft also nichts.

Folgendes sollte klappen:
Code:
item1 = uimenu(handles.ContextMenu(1),...
   'Checked','on',...
   'Label','test',...
   'Callback', @ContextMenuAction);

mit
Code:
function ContextMenuAction(hObject,callbackdata,handles)
% Wird beim Wechsel eines Kontextmenus ausgeführt

handles = guidata(hObject); % die entscheidende Zeile      
% Position 1: nachfolgender delete Befehl wird nicht ausgeführt
delete(handles.item(1));

t=linspace(0,pi);
handles.item(1)=plot(t,sin(t));

% Position 2: nachfolgender delete Befehl wird ausgeführt
% delete(handles.item(1)); <-- sollte weggelassen werden

% guidata(gcbo,handles); <-- ist an sich nicht notwendig

end


Falls es damit Probleme gibt, bitte ein soweit funktionierendes Minimalbeispiel (d.h. inklusive Initialisierung von handles.item(1) ) posten.

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

Forum-Newbie

Forum-Newbie


Beiträge: 7
Anmeldedatum: 02.01.16
Wohnort: ---
Version: R2016b
     Beitrag Verfasst am: 03.01.2016, 19:20     Titel:
  Antworten mit Zitat      
Hallo Harald

Nun funktiontiert es! Besten Dank für Deine Hilfe!

Grüsse
sputnik644
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.