Make a button push another button. Matlab GUI - matlab

I'm building a GUI that shows images when I push a button, but there are a lot of images, and sometimes I want to jump over a number of images, so what I'm trying to do is, get a edit texbox, where I put the number of the image I want to go, push a button to push the other button until i get to the desired image. I want to make this way( pushing the other button x times to get to the desired image) because there are a bunch of parallel stuff happening at the same time the image is passing to the other.
so my code for the button is:
function pushbutton14_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton14 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
i = str2double(get(handles.edit4, 'String'));
while handles.counterN < i
pushbutton1_Callback(hObject, eventdata, handles);
guidata(hObject, handles);
end
So every time I push button 14, I want to get it to push the button 1, until the counter(which is added 1n every time button 1 is pushed) gets to the value in edit4.
But for some reason the guidata is not updated, so the counter always stays as 1.
I have guidata(hObject, handles); , in the end of the button 1 function... so I don't understand why is not updated, I also tried without guidata(hObject, handles); in the while loop

pushbutton1_Callback is incrementing handles.counterN, but you never get the incremented value. In fact, you are immediately overwriting it with 1 when that callback returns. Remember that within the scope of pushbutton14_Callback, handles.counterN is 1. pushbutton1_Callback may be incrementing the counter, but not within the scope of the calling function. Setting it with guidata will not update the value in pushbutton14_Callback until you call handles = guidata(hObject);. Since pushbutton1_Callback has already called guidata(hObject, handles);, get instead of setting the data:
Replace guidata(hObject, handles); with handles = guidata(hObject);.

Related

GUI in matlab, loop of images in axes

So I'm building a classifier of images. In the GUI a image loads and insert a value on a text box, and push a button. I'm having a problem loading the image in the axes. Because when the axes function is called the handles is zero(due to:% handles empty - handles not created until after all CreateFcns called). And my problem is, how do I get to just call one image at a time for the axes.
The ideal solution, is I create a handles.images=imagedatastore, and every time I push the button I add to a counter(which I already have made) and then that give the indices to get the image from the datastore. My problem with this is that I can't get the first picture, because in the beginning the handles are empty. I have made the callfunction for the axes:
% --- Executes during object creation, after setting all properties.
function axes1_CreateFcn(hObject, eventdata, handles)
% hObject handle to axes1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles empty - handles not created until after all CreateFcns called
[pict_croped,Nphotos,Date_img] =getcropedimagages;
handles.img =pict_croped;
i=readimage(handles.img,1);
% axes(hObject)
imshow(i)
% Hint: place code in OpeningFcn to populate axes1
but this has two problems, first, I don't really want to call the function that creates the datastore all the time I push the button, second, I still can't get the indice of the counter to be in the function,if I have:
i=readimage(handles.img,handles.counter)
it will give me the error in the first time, of not having handles.counter
Any idea how to solve this?This is the first GUI I'm building.
The issue is very clearly in the comment that GUIDE provides for you. The handles struct isn't populated until all CreateFcn have been run so you'll want to use the OpeningFcn to do any initialization of the graphics objects. You can then add any data you need to the handles struct and save it using guidata so that it's available from within all of your other callback functions.
function OpeningFcn(hObject, eventData, handles)
[pict_croped,Nphotos,Date_img] = getcropedimagages;
handles.img = pict_croped;
i = readimage(handles.img,1);
imshow(i, 'Parent', handles.haxes1)
% "Save" the changes to the handles object
guidata(hObject, handles)
Well, I end up with:
in the opening fucntion:
i = readimage(handles.img,handles.counter);
imshow(, 'Parent', handles.axes1)
and in the button call back:
i = readimage(handles.img,handles.counter);
imshow(i, 'Parent', handles.axes1)
inthe end is a very simple solution, I think I was just mind blocked over the first iteration...

How to detect a push button press and release in matlab

i have a GUI based in matlab 2015 to code
when i push/ press the button one of edit box data keeps changing but i want its value to keep on changing according to my call back until i release it
for now i have to keep on clicking my push button again and again which changes my edit box value
Kindly suggest me a workarround
% --- Executes on button press in pushbutton27.
function pushbutton27_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton27 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
Freq = (str2double(get(handles.edit4,'String')))+ 0.001;
if Freq > 20
set(handles.edit4,'String','20');
else
set(handles.edit4,'String',num2str(Freq));
end
uicontrol has only the Callback and ButtonDownFcn properties that respond to mouse clicks. If the property Enable of the uicontrol is set to 'on', only the function specified in Callback reacts to left-clicks. If the property is set to 'off' or 'inactive' it also reacts to right-clicks. Because for inactive uicontrols you cannot change the Value by clicking on it, I don't see a direct solution using uicontrol.
A solution is to use the figure's WindowButtonDownFcn and WindowButtonUpFcn properties. For the button down you could use something like:
function buttondown(hobj,~,hedit)
hobj.UserData = true;
while hobj.UserData
pause(0.2); % put a pause so it doesnt change too fast
hedit.String = datestr(now); % you can set it to anything you want here
end
end
For the button up:
function buttonup(hobj,~)
hObj.UserData = false;
end
Of course, if you have multiple buttons that have to work this way, in the buttondown function you must test where the cursor's position is that by checking the CurrentPoint property.

Using addlister in MATLAB GUI seems to "delete" existing handles

I am quite new to MATLAB GUI programming (using GUIDE sorry) and I have the following issue: The GUI displays on an axis an image sequence stored in a cell array. I have a couple of pushbuttons and a slider to scroll through the sequence. In order to get a 'continuous slider' I use a listener, which kind of works but creates some problems:
1) When I press the slider, a figure is created and the first frame of the sequence is displayed in it, but as I move the slider the sequence is displayed in the axis of my GUI (which is what I want) and the figure becomes empty. Can anybody tell me why this figure is created and how can I avoid it?
2) Once I press the slider button and thus use the listener, all handles inside the GUI are not functionnal as Matlab does not recognize them and I'm stuck with a functionnal slider/display but I can't use the pushbuttons.
Any ideas on why this happens? Here is the code I use in the Create Function of the slider:
function slider2_Frame_Video_Callback(hObject, eventdata, handles)
hListener = addlistener(hObject,'ContinuousValueChange',#(a,b) slider2_Frame_Video_Callback(hObject, eventdata, handles)); % a and b are dummy arguments
guidata(hObject,handles)
In the slider callback, the code looks like this (basically imshow in the current axis):
axes(hAxis)
imshow(Movie{frame},'parent',hAxis);
drawnow
% This does not work either as handles.edit_FrameNumber is not recognized by Matlab
set(handles.edit_FrameNumber, 'String', frame);
guidata(hObject,handles);
Any hints are welcome thanks!
I wonder if part of the problem is that a listener is being instantiated each time the user moves the slider since the listener code is within this callback AND that the callback being provided to the listener (seems like some kind of strange back-and-forth there). So every time the user releases the mouse button after a slide, a new listener is created. This may be causing some problems with the other buttons not being responsive.
Rather than instantiating the listener there, I would do this in the Opening_Fcn of your GUI:
% --- Executes just before frameSlider is made visible.
function frameSlider_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject handle to figure
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% varargin command line arguments to frameSlider (see VARARGIN)
% Choose default command line output for frameSlider
handles.output = hObject;
if ~isfield(handles,'hListener')
handles.hListener = ...
addlistener(handles.slider1,'ContinuousValueChange',#respondToContSlideCallback);
end
% Update handles structure
guidata(hObject, handles);
My GUI is named frameSlider; yours will be something else. The above creates one listener with a callback to a function that you will need to define in the same *.m file, respondToContSlideCallback.
A sample body for the callback that is to respond to the continuous slide is
% --- Executes on slider movement.
function respondToContSlideCallback(hObject, eventdata)
% hObject handle to slider1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% Hints: get(hObject,'Value') returns position of slider
% get(hObject,'Min') and get(hObject,'Max') to determine range of slider
% first we need the handles structure which we can get from hObject
handles = guidata(hObject);
% test to display the current value along the slider
disp(['at slider coordinate ' num2str(get(hObject,'Value'))]);
If you run this code, the Command Window will display continuously the slider coordinate as you move the slider from end to end.
Your above code has a Movies cell array. How is that being accessed by your callback? Is it a global variable or ..? Where does hist come from? If Movies is the result of some other function call, then it can be saved to handles too (in whichever location it gets loaded from file). I suppose you will also have to map the slider control coordinates to the number of frames that you have (though maybe you have already done this?).

Show whether the GUI is running or not in matlab GUIDE

I'm currently creating a GUI using mathlab GUIDE. Since the GUI is very slow I'd like to add an edit_text uicontrol in order to show whether the GUI is running or not.
For instance I have a push_button that changes the plot in an axes. When the user click on this button the GUI takes several seconds to perform the new plot. What I want to do is setting the edit_text with the string 'running' as soon as the button was pressed. When the callback is done and the plot plotted I'd like to set the edit_text with another string : 'ready'.
I used the following code :
function push_button_Callback(hObject, eventdata, handles)
% hObject handle to push_button (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
set(handles.edit_text,'String','Running...');
%a bunch of code...
set(handles.edit_text,'String','Ready.');
guidata(hObject,handles);
I hoped that once the callback is called, the GUI would display 'running...' on my edit_text. Apparently I was wrong. When running the GUI and pressing the push_button the plot changes but the edit_text remains the same.
Then I tried something else using the ButtonDownFcn callback. My idea was that the latter callback would be executed before the actual callback (written above). Here is the code :
function push_button_ButtonDownFcn(hObject, eventdata, handles)
% hObject handle to push_button (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
set(handles.edit_text,'String','Running...');
guidata(hObject,handles);
The problem is that the ButtonDownFcn callback isn't executed every time. As GUIDE says about the latter callback :
% --- If Enable == 'on', executes on mouse press in 5 pixel border.
% --- Otherwise, executes on mouse press in 5 pixel border or over str22.
Obviously I want my push_button to be enabled, otherwise it won't work the way I want. So I don't know what else to try.
Has someone any idea how I could manage to do that ?
You could try doing
set(handles.edit_text,'String','Running...');
drawnow;
%a bunch of code...
The GUI might not be updated until you get to
set(handles.edit_text,'String','Ready.');
So forcing it to update with drawnow might work for you.

How do I add my own variables to the handles structure from within a custom function of mine?

I have a question to ask the MATLAB gurus here ..
So here is my code (only showing lines of code which are relevant to the problem here):
mainProcess(hObject, handles)
handles.Checkpoint2 =1;
guidata(hObject, handles);
function testGUI1_OpeningFcn(hObject, eventdata, handles, varargin)
handles.output = hObject;
handles.Checkpoint1 = 1;
mainProcess(hObject, handles);
handles.Checkpoint3 = 1; //EDIT: Checkpoint2 is also not visible at this line
guidata(hObject, handles);
handles.Checkpoint4 = 1;
function saveAndContinueButton_Callback(hObject, eventdata, handles)
(breakpoint here) --> faceDatabase(handles.currentImageIteration).lookingTowardsCamera=handles.lookingAtCamera;
So in the above code, I'm making these 'checkpoints' at different parts of the code, and seeing which of them are visible when a save and continue button is clicked separately ...
Checkpoint1 is created BEFORE calling my custom function called mainProcess, Checkpoint2 is created within the code of mainProcess, and Checkpoint3 is created AFTER mainProcess is finished executing and the control is back with the function that called it, which is testGUI1_OpeningFcn ... And Checkpoint4 is created WITHIN testGUI1_OpeningFcn, but AFTER the handles structure is updated in the testGUI1_OpeningFcn code ..
So my question is this, when the button is clicked and I see what is visible at that point, Checkpoint 1 and 3 are visible to the button Callback code, but Checkpoints 2 and 4 are NOT visible ... I understand that Checkpoint4 is not visible because it was created AFTER the handles structure was updated in testGUI1_OpeningFcn's code ... But why is Checkpoint2 not visible, even when at the end of mainProcess's code, I did put a line:
guidata(hObject, handles);
I mean the mainProcess function is getting references to both hObject and handles, so it should have write access to it, right ?
So why isn't Checkpoint2 not visible to the button's Callback code .. ?
Any clues ?
EDIT: I just tried to see if Checkpoint2 is visible even within mainProcess's calling function, right after the control is returned the caller, and even there Checkpoint2 is not visible (see the EDIT in the code above) ..
That's correct, you need to call guidata to update the handles variable you have. However, guidata needs an argument. I think the right command would be:
handles = guidata(hObject);
You may find this link helpful:
http://www.mathworks.com/matlabcentral/answers/10197-guidata-doesn-t-work-the-way-i-expected-it-to
I believe you need to add the following just after calling mainProcess()
handles = guidata();
In general, the 'handles' struct is passed by value to the guidata() function. Therefore, mainProcess() cannot change the handles structure -- just attach the existing structure to the handle. Before making further modifications you need to get it back (using handles=guidata()), update it and set it again with guidata(h, handles).
Let me know if this is not clear enough (or just does not work :)
Edit
You need to change the code like this:
function testGUI1_OpeningFcn(hObject, eventdata, handles, varargin)
handles.output = hObject;
handles.Checkpoint1 = 1;
mainProcess(hObject, handles);
handles = guidata(); // <--- new line
handles.Checkpoint3 = 1; //EDIT: now checkpoint2 will be visible here
guidata(hObject, handles);
handles.Checkpoint4 = 1;
guidata(hObject, handles); // Otherwise Checkpoint4 will not be bound to hObject