Verfasst am: 04.11.2014, 11:23
Titel: Timer stoppt nicht nach Löschen der GUI
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..
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
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
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:
in die catch -Anweisung springt. Die Funktion sieht so aus:
Code:
function timercb(obj,type,val,event)
%TIMERCB Wrapper fortimer 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 ifisa(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. ifisa(val, 'function_handle')
val = {val};
end % Execute callback function. ifiscell(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:
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.
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
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.
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.
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...
im Zweifelsfall ein try-catch in die Funktionen, die den Fehler erzeugen, und im catch-Teil nichts reinschreiben. So sollten die Fehlermeldungen verschwinden.
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...
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.
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
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.