I'm doing an interface in app designer where I turn on my webcam when I press a button(Empezar button), the only problem is that I can't find a way on how to stop my webcam, It's on a loop and I need to finish that loop when I press another button (stop button), but I've tried a lot of things and nothing really seems to work, I tried with a buttonpressfcn didn't work, opening a figure and when it closes the figure the vid stops didn't work either, any ideas? I know how to stop the vid in GUIDE but I have to use App Designer and It's not the same I think :(
properties (Access = public)
UIFigure matlab.ui.Figure
StopButton matlab.ui.control.Button
EmpezarButton matlab.ui.control.Button
UIAxes matlab.ui.control.UIAxes
end
% Callbacks that handle component events
methods (Access = private)
% Button pushed function: EmpezarButton
function EmpezarButtonPushed(app, event)
% clear all;
micamara=webcam(1);
micamara.Resolution='640x360';
micamara.Brightness=10;
%ventana=app.StopButton.ButtonPushedFcn;
%while ishandle(ventana)
ventana=figure;
while ishandle(ventana)
img=snapshot(micamara);
imshow(img,'Parent',app.UIAxes);
end
end
% Button pushed function: StopButton
function StopButtonPushed(app, event)
global ventana;
ventana=1;
end
end
Hey engineerinprocess (aren't we all..?)
The infinite loop in your EmpezarButtonPushed callback makes it impossible for Matlab to handle other callbacks, like your StopButtonPushed callback. That's way it does not work.
The proper way of solving this would be using a timer.
The setup-code I would move to the 'startupFcn' of your app, and be sure to store the micamera as a property of your app. You'll need it later. In the startupFcn you also initialize a timer with a certain period.
A timerFcn callback can then do the things you have in your while loop.
The EmpazarButtonPushed now starts the timer (if not already running)
The StopButtonPushed callback should stop the timer (if running).
You should also add a CloseRequestFcn callback for your figure, where you stop and delete your timer object. Another thing I usually do during development, EngineerInProcess, is to put the contents of the timer callback in a try/catch block, where in the catch block I display the error message and stop the timer.
There is actually an example in the appdesigner on how to use timers in apps. You may want to check that out as well.
Related
I want to have a ui button that will start and pause a simulation. The script I want to run is a for loop simulation, say the script name is simulation.m.
I set the push button as follows.
start.button = uicontrol('Style','pushbutton','units','normalized',...
'String','Start','Position',[0.1,0.93,0.1,0.05], ...
'Callback',#start_call);
I can't figure out what to write in the callback function (either for running the script or for pausing it
function [] = start_call()
simulation.m;
end
You've basically got it right, you just need to add two things: the callback always takes two input arguments, so even if you don't use them, the function definition needs them. A script is run using the run command. Just change your callback to
function [] = start_call(source, eventdata)
run('simulation.m');
end
Remark: arguments that are not used are commonly replaced by the shorthand ~, which would then read
function start_call(~, ~)
You can also obviously drop the square brackets, if there is no output.
It's my first post here, so hello everyone!
My question is about MATLAB GUI interface. In my code, there is a function callback from a pushbutton and I would like to disable every push/slide-able element in my GUI during processing this callback. Unfortunatelly, when I set 'enable' property of these elements to 'off' at the beginning of a callback and then I set it back to 'on' at the end, property doesn't change.
I think I know why it happens. Probably because if callback changes anything, it happens just after the function is finished and every change inside it does not affect any element outside of the function until the processing is done. That's why I don't see all these elements disabled - because at the end of the function I set everything 'on' and that's the only thing which takes place at all.
Regarding to this - is there any option I can change 'enable' property DURING executing a function? Code is shown below:
function [] = mListLaunchButton_call(varargin)
// Some global declarations
global a phi launchBlanker
global servoNumber servoZeroPosition servoDegreePerDegree servoDirection
// Assigning a class
Manual = varargin{3};
// Enabling "Stop" button and disabling everything else
set(Manual.listStopButton,'enable','on');
set(Manual.listSaveButton,'enable','off');
set(Manual.listDeleteButton,'enable','off');
set(Manual.listClearButton,'enable','off');
set(Manual.listLaunchButton,'enable','off');
set(Manual.closeButton,'enable','off');
for i = 1 : 5
set(Manual.sliderDOF(i),'enable','off');
end
%%%%%%%%%%%%%%%%%%%% HERE FUNCTION DOES SOME STUFF %%%%%%%%%%%%%%%%
// Disabling "Stop" button and enabling eveything else
set(Manual.listStopButton,'enable','off');
set(Manual.listSaveButton,'enable','on');
set(Manual.listDeleteButton,'enable','on');
set(Manual.listClearButton,'enable','on');
set(Manual.listLaunchButton,'enable','on');
set(Manual.closeButton,'enable','on');
for i = 1 : 5
set(Manual.sliderDOF(i),'enable','on');
end
Try using the drawnow command after your initial enabling/disabling of GUI controls and before the line:
%%%%%%%%%%%%%%%%%%%% HERE FUNCTION DOES SOME STUFF %%%%%%%%%%%%%%%%
This should cause MATLAB to flush the queued GUI events and update your screen before moving onto the meat of the function.
I am working on some modifications to EEGlab's eegplot function (things like vim-style navigation etc.) that need to work through WindowKeyPressFcn.
However, the callback is not being called for some reason. I have been debugging the issue for some time and am a bit lost. I am looking for suggestions on what might be wrong. Unfortunatelly the eegplot function is big, complex and somewhat convoluted and I was unable to reproduce the issue in a simple example. Therefore I am looking for general suggestions on why a function handle that is clearly present in WindowKeyPressFcn might stop being used at some point.
Here is what I have learned so far:
If I go to debug mode in eegplot (set a breakpoint near the end of the setup function [the first half of eegplot]) I am able to run the WindowKeyPressFcn at least once.
However - the function stops being called at some point during debug (sometimes even after being called only once).
If I run eegplot without debug (that is wait for it to finish and return control to me) I am unable to call WindowKeyPressFcn by pressing a key. The function handle is still present in WindowKeyPressFcn property of the figure.
Whener the WindowKeyPressFcn is not being used when I press a key, I can still call it with:
figh = gcf;
fun = get(figh, 'WindowKeyPressFcn');
ev.Key = 'rightarrow';
ev.Character = ' ';
ev.Modifier = [];
feval(fun, figh, ev);
So the function handle is 'healthy' so to speak, but for some reason it is not being used any more when a key is pressed and the figure has focus. When and why something like this could happen? Any ideas on things I should check to understand this issue?
Update:
I found out that WindowKeyPressFcn callback can sometimes be blocked by some window listeners, and tried out the following solution:
hManager = uigetmodemanager(gcf);
set(hManager.WindowListenerHandles,'Enable','off');
It doesn't work - WindowKeyPressFcn is still not called when I press a key. :(
Update 2:
Another thing that does not work:
chld = get(gcf, 'Children');
tp = get(chld, 'type');
chld = chld(strcmp(tp, 'uicontrol'));
set(chld, 'KeyPressFcn', #eegplot_readkey_new)
(eegplot_readkey_new is the function I use for reacting to keypresses)
Update 3:
And another one not working:
addlistener(gcf, 'WindowKeyPress', #eegplot_readkey_new);
Ok - I fiugred it out, although the solution is weird to say the least.
For some mysterious reason using linesmoothing undocummented property prevents WindowKeyPressFcn from being called. I have absolutely no idea why...
I am creating an object i want it to make it draggable when i apply touch event on it, and if
user touches that object for more than 5 sec then that object must not work as draggable object but
then i have to call some other function, after that i want to clear the counter so that after next touch it will be reinitialized..... how can it be achieved in corona i was trying this with Timer = os.time() but could not get the perfect result. Please suggest any idea... thanks
local function callfunc( event )
local phase = event.phase
if "began" == phase then
Timer = os.time()
if Timer>5 then
func1()
else
func2()
end
end
Runtime:addEventListener("touch",callfunc)
i'm assuming that you cannot get what you achieve because you did not remove the listener when going to another function see my code as a reference:
local function func1()
--set the object as draggable
end
local function func2()
--remove the listener of the func1() and set another listener here
--call other function here
end
local function callfunc( event )
local phase = event.phase
if "began" == phase then
Timer = os.time()
if Timer>5 then
func1()
else
func2()
end
end
Runtime:addEventListener("touch",callfunc)
you can post another snippet of your code where the problem occurs if the idea above does't work since i only assume the problem that you have encountered. its hard to point out where the problem occur if there is only a snippet of code.
The event table passed on touch events has the time the event happened. I would on the began phase, store the event.time. Then when you get your first moved phase, if the time is over 5 seconds behave one way, else behave the other.
I would be very grateful for help, advice or suggestion. I have an application to control geodetic instrument using synchoronous interface. However some commands are asynchronous by its nature, e.g. GetReflectors. After this command is triggered I receive as many server answers as is the number of available reflectors. So I have registered an COM event and associate handler function. So far so good. I can display the data coming but I do not know how to pass some variable to the main function. I tried to save variable as .mat file or in .txt file and read it. Actually it works in Matlab but it does not works in compiled .exe aplication (Error firing event). Even disp command does not work in compiled aplication (display nothing). So the main question is: how to pass variables from handler to main function. Is there a way? Global variables? Thank you Filip
Edit: I am adding an code to demostrate the problem... I need to save Reflector Name and Reflector ID so as the user can choose one (because there are multiple events coming with different Reflectors).
function pushbutton_GetReflectors_Callback(hObject, eventdata, handles)
ltsync = actxserver ('LTControl.LTCommandSync2'); %Act as server: LTConnect2
ltsync.events() %List of all COM events
ltsync.registerevent({'ReflectorsData' 'ReflectorsHandler'}) %Register event
ltsync.GetReflectors() %Ask instrument for reflectors
pause(3) %Time to receive answers
end
function ReflectorsHandler(varargin) %Handler of the event ReflectorsData
%var1,var2,reflectorID,reflectorName,var5,surfaceOffset,reflectorsTotal,var8,var9
disp('Reflector Data:');
disp(varargin{3}) %Reflector ID
disp(varargin{4}) %Reflector name
end
I believe you can solve this problem by passing a function handle to registerevent instead of just the string function name, and creating a class to allow you to pass the data back. First, the class:
classdef ReflectorsResponse < handle
properties (SetAccess = private)
reflectors
responseComplete = false;
reflectorsTotal = NaN;
end
methods
function respond(obj, varargin)
% Create a struct for each reflector (or you could define
% another class, but let's keep it simple for the time being)
newRefl = struct();
newRefl.ID = varargin{3};
newRefl.name = varargin{4};
newRefl.surfaceOffset = varargin{6};
% ... store other properties in struct
% Store this reflector
obj.reflectors = [obj.reflectors; newRefl];
% Store total reflector count and check for completion
if isnan(obj.reflectorsTotal)
obj.reflectorsTotal = varargin{7};
end
if length(obj.reflectors) == obj.reflectorsTotal
obj.responseComplete = true;
end
end
end
end
You can then use this by making the respond method your handler:
function pushbutton_GetReflectors_Callback(hObject, eventdata, handles)
% Create the response object and associated handler function handle
response = ReflectorsResponse();
handlerFun = #(varargin)response.respond(varargin{:});
ltsync = actxserver ('LTControl.LTCommandSync2'); %Act as server: LTConnect2
ltsync.events() %List of all COM events
ltsync.registerevent({'ReflectorsData' handlerFun}) %Register event
ltsync.GetReflectors() %Ask instrument for reflectors
% Wait for request to complete
while ~response.responseComplete
pause(0.1);
drawnow update;
% NOTE: Should add a timeout to this loop
end
% Do stuff with response.reflectors
end
This will wait until there has been a response for each of the reflectors, the number of which is determined from the first response. Note that you should add a timeout to the while loop, otherwise you risk waiting infinitely.
If there are lots of these asynchronous requests that you have to handle, I would suggest encapsulating the entire request/response sequence (including the creation of the ActiveX server, setup of the event handler, and waiting for the response(s)) in a generalised base class, and deriving specific subclasses for each different request.