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

Timer stoppt nicht nach Löschen der GUI

 

nuby
Forum-Newbie

Forum-Newbie


Beiträge: 5
Anmeldedatum: 04.11.14
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 04.11.2014, 11:23     Titel: Timer stoppt nicht nach Löschen der GUI
  Antworten mit Zitat      
Hallo MatLab-Gemeinde,

ich habe eine Timer-Funktion definiert, in welcher mit TimerFcn eine Callback-Funktion in einem bestimmten Zeitintervall ausgeführt wird. Der Timer soll über eine andere Callback-Funktion mit StopFcn beendet werden. Mit der im Timer angegebene Callback-Funktion für TimerFcn soll innerhalb eines GUI-figures (HF.Hauptfenster) die Mauszeigerposition abgefragt werden. In der Callback-Funktion für StopFcn wird das GUI-figure dann geschlossen.

>>>PROBLEM: Der Timer wird nicht gestoppt und will die Callback-Funktion für TimerFcn weiter ausführen, allerdings ist das object (GUI-figure) schon gelöscht!

>>>FEHLERMELDUNGEN:
Error while evaluating StopFcn for timer 'timer-3453'
Invalid or deleted object.
Error while evaluating TimerFcn for timer 'timer-3454'
Invalid or deleted object.

Diese Fehlermeldungen werden immer wieder nacheinander mit schwarzer Schrift im workspace angezeigt und müllen den kompletten workspace zu, sodass ich die eigentlichen Fehlermeldungen, die mein Programm auswirft nicht mehr lesen kann.. Mad
Nach gewisser Zeit (ca. 10 Sekunden) stoppt der Timer, es werden keine weiteren Fehlermeldungen angezeigt.

>>>PROGRAMMCODE:
Code:

function Zeitfkt(~,~)
%Timer-Funktion
global HF
HF.timer=timer('Timerfcn',@Zyklische_Abfrage,'BusyMode','Queue','Period',50,'ExecutionMode','fixedDelay','StopFcn',@Program_Schliessen);
start(HF.timer);
end

function Zyklische_Abfrage %(es werden zwei Funkionen aufgerufen):
Funktion_1
Funktion_2
end

function Funktion_1(~,~)
global HF
PosAkt = get(HF.Hauptfenster,'CurrentPoint');
......%mache etwas...für best. Mauspos. werden Textboxen angezeigt
end

function Funktion_2(~,~)
global HF
set(HF.Hauptfenster,'WindowButtonDownFcn',@Untermenue_Oeffnen);
end

function Untermenue_Oeffnen(~,~)
global HF
PosAkt = get(HF.Hauptfenster,'CurrentPoint');
......%mache etwas...für best. Mauspos. und Mausklick wird neue GUI-figure aufgerufen
end

function Program_Schliessen(~,~)
global HF
delete(HF.Hauptfenster)
end


Der Timer will also auf ein object zugreifen, welches aufgrund "delete(HF.Hauptfenster)" nicht mehr existiert..? Wieso wird der timer, also HF.timer durch die StopFcn nicht gestoppt?

Ich hoffe ihr könn tmir helfen! Das treibt mich in den Wahnsinn Twisted Evil

Vielen Dank schonmal!
Grüße
NUBY
Private Nachricht senden Benutzer-Profile anzeigen


Harald
Forum-Meister

Forum-Meister


Beiträge: 24.499
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 04.11.2014, 21:04     Titel:
  Antworten mit Zitat      
Hallo,

stoppe doch beim Schließen den Timer?

Code:
function Program_Schliessen(~,~)
global HF
delete(HF.Hauptfenster)
stop(HF.timer)
end


Globale Variablen sollten im übrigen möglichst vermieden werden, siehe
http://www.mathworks.com/help/matla.....data-among-callbacks.html

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

Forum-Newbie

Forum-Newbie


Beiträge: 5
Anmeldedatum: 04.11.14
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 05.11.2014, 12:05     Titel:
  Antworten mit Zitat      
Hallo Harald,

danke schonmal für deine Antwort!
Ich hätte gleich erwähnen sollen, dass ich dass schon alles versucht habe.
Also ich habe in der function Programm_Schliessen schon folgendes probiert (alle auskommentierten Befehle):

Code:
function Program_Schliessen(~,~)
global HF
% stop(HF.timer)
% delete(HF.timer)
% clear(HF.timer)
% delete(timerfind)
% stop(timerfind)
delete(HF.Hauptfenster)
% stop(HF.timer)
% delete(HF.timer)
% clear(HF.timer)
% delete(timerfind)
% stop(timerfind)
% clear all
end


Ich habe also jeweils vor und nach dem Löschen des figures den die timer-Variable HF.timer und auch alle nicht sichtbaren timer mit timerfind gelöscht, bzw. gestoppt. Leider hat keiner der Befehle das Problem beseitigt.
Das Programm hat mittlerweile halt schon relativ große Dimensionen angenommen und besteht aus ca. 40 Funktionen. Da konnt ich auf globale Variablen nicht verzichten.

>>>Neue Infos:
Wenn ich auf "delete(HF.Hauptfenster)" den breakpoint setze, das Programm ausführe und das figure über "x" schließe, wird im workspace eine Fehlermeldung ausgegeben: "986 delete(HF.Hauptfenster)". Danach führe ich das Programm Schrittweise weiter mit Step aus. Das Programm springt vom Ende der function Programm_Schliessen in eine neue function timercb.m (MatLab-Funktion). Darin befindet sich eine try/catch-Anweisung, in der das Programm von der Zeile:

Code:
feval(val{1}, obj, eventStruct, val{2:end});


in die catch -Anweisung springt. Die Funktion sieht so aus:
Code:

function timercb(obj,type,val,event)
%TIMERCB Wrapper for timer object callback.
%
%   TIMERCB(OBJ,TYPE,VAL,EVENT) calls the function VAL with parameters
%   OBJ and EVENT.  This function is not intended to be called by the
%   user.
%
%   See also TIMER
%

%    Copyright 2001-2008 The MathWorks, Inc.

if ~isvalid(obj)
    return;
end
try  
    if isa(val,'char') % strings are evaled in base workspace.
        evalin('base',val);
    else % non-strings are fevaled with calling object and event struct as parameters
    % Construct the event structure.  The callback is expected to be of cb(obj,event,...) format
        eventStruct = struct(event);
        eventStruct.Data = struct(eventStruct.Data);
   
   % make sure val is a cell / only not a cell if user specified a function handle as callback.
        if isa(val, 'function_handle')
            val = {val};
        end  
     % Execute callback function.
        if iscell(val)
          feval(val{1}, obj, eventStruct, val{2:end});
        else
            error(message('MATLAB:timer:IncorrectCallbackInput'));
        end
    end        
catch exception
    if ~ strcmp(type,'ErrorFcn') && isJavaTimer(obj.jobject)
        try %#ok<TRYNC>
           obj.jobject.callErrorFcn(exception.message,exception.identifier);
        end
    end
    identifier = 'MATLAB:timer:badcallback';
    %Displays the exception message without throwing it.
    disp(getReport(MException(identifier, '%s', ...
                getString(message(identifier, type, get(obj,'Name'), exception.message)))));
end
 

Durch den letzten Befehl in dieser Funktion wird eine Fehlermeldung im command window ausgegeben:
"Error while evaluating StopFcn for timer 'timer-1897'"
Invalid or deleted object.

Nach Beendigung dieser function springt MatLab weiter zur nächsten function timercb.m (MatLab-Funktion). Die sieht so aus:
Code:


function timercb(varargin)
%TIMERCB Wrapper for timer object callback.
%
%   See also TIMER
%

%    Copyright 2004 The MathWorks, Inc.

%Create a timer object out of the JavaTimer, and then call the object
%timercb.
h = handle(varargin{1});
t = timer(h);
timercb(t, varargin{2:end});


Hier wird die letzte Zeile zuerst ausgeführt und anschließend die erste und zweite und wieder die dritte Zeile. Beim Sprung in die erste Zeile kommt die Meldung:

11 h = handle(varargin{1});

Dann springt MatLab von hier wieder in die Hauptfunktion, zu meinem breakpoint bei "delete(HF.Hauptfenster)". Wenn ich das Programm weiter mit Step ausführe, wird der eben beschriebene Ablauf, also erst in die erste Funktion und dann die zweite Funktion von neuem ausgeführt. Dieser Ablauf findet dann immer wieder statt.

Es werden also nach Beendigung des Programms die dem Befehl timer hinterlegten Funktionen aufgerufen, wobei MatLab in der ersten timercb.m von der try-Anweisung in die catch-Anweisung springt, da ein Fehler aufgetreten ist. Es wird in der catch-Anweisung eine Fehlermeldung ausgegeben.
Anschließend wird (wie auch immer - wird nicht in erster timercb.m aufgerufen) eine zweite, gleichnamige Funktion timercb.m aufgerufen. Danach springt MatLab zurück ins Hauptprogramm.

>>>Fragen:
1. Was machen die beiden timercb.m?
2. Warum wird der timer durch Programm_Schliessen nicht gestoppt (siehe function Zeitfkt)?
3. Wie kann ich den timer mit Beendigung des Programms stoppen?

Fällt dir Harald, oder jemand anderem dazu irgendetwas ein? Das wäre super! Ich weis, das ist viel Text, aber anders kann ich das Problem nicht beschreiben. Confused

Viele Grüße
NUBY
Private Nachricht senden Benutzer-Profile anzeigen
 
denny
Supporter

Supporter



Beiträge: 3.853
Anmeldedatum: 14.02.08
Wohnort: Ulm
Version: R2012b
     Beitrag Verfasst am: 05.11.2014, 16:30     Titel:
  Antworten mit Zitat      
Hallo

dein Fehler liegt einfach darin, dass die Funktion @Program_Schliessen mehrmals aufgerufen wird: Einmal durch die GUI und zweites Mal durch den Timer. Deswegen kommt zu dem Fehler.

richtig wäre diese Stop-Funktion in dem Timer gänzlich zu entfernen, weil diese ist nur dafür da um weitere Anweisung nach dem Stoppen des Timers ausführen.

Code:

function Zeitfkt(~,~)
%Timer-Funktion
global HF
HF.timer=timer('Timerfcn',@Zyklische_Abfrage,'BusyMode','Queue','Period',50,'ExecutionMode','fixedDelay');
start(HF.timer);
end



function Program_Schliessen(~,~)
global HF
stop(HF.timer)
delete(HF.Hauptfenster)
end

 


Außerdem wurde ich in Timer-Callback eine Überprüfung machen, ob das Handle der GUI noch existiert, weil bevor der Timer gestoppt wird, wird zuerst der Timer Callback zu Ende ausgeführt, da kann es sein, dass die Funktion Program_Schliessen dabei schneller ist.
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


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

Zitat:
Das Programm hat mittlerweile halt schon relativ große Dimensionen angenommen und besteht aus ca. 40 Funktionen. Da konnt ich auf globale Variablen nicht verzichten.

Das wage ich zu bezweifeln. Ich würde sogar sagen: ein Verzicht auf globale Variablen ist zwingend notwendig, wenn du die Anwendung mal debuggen musst (was bei 40 Funktionen nicht so unwahrscheinlich ist). Ansonsten kann es dir passieren, dass eine Variable einen ungültigen Wert hat - und das einzige, was du weißt ist: es ist in einer der anderen 39 Funktionen passiert. Dann viel Spaß bei der Fehlersuche.

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

Forum-Newbie

Forum-Newbie


Beiträge: 5
Anmeldedatum: 04.11.14
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 11.12.2014, 09:59     Titel:
  Antworten mit Zitat      
Hallo nochmal,

zunächst erstmal danke für die Tipps! Bisschen spät zwar, aber besser als nie! Diese nachlaufenden Fehlermeldungen des Timers, nach Schließen der figure konnte ich dann durch dennys Beitrag beseitigen. Danke dafür!

Das Problem ist nun aber:
Beim Starten des Skripts läuft die Timer-Fehlermeldung nun vor...
D.h. mein Command Window wird bevor die figure öffnet mit den oben beschriebenen Fehlermeldungen zugeballert. An sich nicht so schlimm, da es mir nur darauf ankam die nachlaufenden Timer-Fehlermeldungen zu beseitigen, sodass ich die "wichtigen" Fehlermeldungen lesen kann.

Falls ihr da noch einen Einfall habt, wäre ich dankbar, ansonsten bleibt es eben so... Laughing

Grüße
Nuby
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.499
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 11.12.2014, 16:34     Titel:
  Antworten mit Zitat      
Hallo,

im Zweifelsfall ein try-catch in die Funktionen, die den Fehler erzeugen, und im catch-Teil nichts reinschreiben. So sollten die Fehlermeldungen verschwinden.

Grüße,
Harald
Private Nachricht senden Benutzer-Profile anzeigen
 
denny
Supporter

Supporter



Beiträge: 3.853
Anmeldedatum: 14.02.08
Wohnort: Ulm
Version: R2012b
     Beitrag Verfasst am: 15.12.2014, 16:09     Titel:
  Antworten mit Zitat      
nuby hat Folgendes geschrieben:
Hallo nochmal,

zunächst erstmal danke für die Tipps! Bisschen spät zwar, aber besser als nie! Diese nachlaufenden Fehlermeldungen des Timers, nach Schließen der figure konnte ich dann durch dennys Beitrag beseitigen. Danke dafür!

Das Problem ist nun aber:
Beim Starten des Skripts läuft die Timer-Fehlermeldung nun vor...
D.h. mein Command Window wird bevor die figure öffnet mit den oben beschriebenen Fehlermeldungen zugeballert. An sich nicht so schlimm, da es mir nur darauf ankam die nachlaufenden Timer-Fehlermeldungen zu beseitigen, sodass ich die "wichtigen" Fehlermeldungen lesen kann.

Falls ihr da noch einen Einfall habt, wäre ich dankbar, ansonsten bleibt es eben so... Laughing

Grüße
Nuby



Hallo der Tipp, habe ich schon in obigen Post gegeben.
Du musst prüfen, ob das Fenster offen ist/existiert, das geht über handle, siehe ISHANDLE -Funktion. Du speicherst das GUI-Handle, bestimmt in einem FELD deiner Struktur, wenn das beim Starten passiert, prüfe ob das Feld da ist, ISFIELD Funktion. Das musst in dem Timer prüfen.

Einfachste Lösung ist TRY-CATCH, aber wenn dort noch andere Fehler passieren, wirst du diese nicht mehr mitbekommen.
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 - 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.