Create slider with dynamic range based on user input matlab gui - matlab

Hi I have a quick question on how to solve this issue. Basically I would like to take the inputs from two edit text boxes and specify them as the min and max of the sliders range. I don't have a problem doing this but as soon as the min is entered the slider disappears because the min is now above the default slider value, which is 0. I understand that the error is because the value is no longer in the range of the min and max, and I want to fix this by updating the value to be above the min in the call back function for the min/max input text boxes. Is there a way I can update the default value to be above min so I can get past this error and actually use the slider?
Warning: 'slider' control cannot have a 'Value' outside of 'Min'-'Max' range
Control will not be rendered until all of its parameter values are valid
Here is what I have tried to do in the call back to the edit box that gets user input for the minimum for the slider:
function input_min_Callback(hObject, eventdata, handles)
value_min=str2double(get(hObject, 'String'));
if value_min > sliderValue_default
set(handles.Input_Transverse_Shear_Layer1, 'Value', value_min+1);
set(handles.Input_Transverse_Shear_Layer1, 'Min', value_min);
end
Any help would be greatly appreciated!
Thanks

Your code looks fine to me. You seem to be missing a guidata(hObject,handles)at the end to update the guidata so this could be the problem (unless it's there but you did not include it in your above snippet).
In any case here is a bit of code that looks very much like yours and works fine. Try it out so you might see what is wrong with yours...
function UpdateSliderMin(~)
clc
clear
close all
%// Create GUI elements and set default slide value
hFig = figure('Position',[200 200 200 300]);
sliderValue_default = 0;
handles.Slider = uicontrol('style', 'Slider', 'Min', -5, 'Max', 10, 'Value',sliderValue_default, 'Units','normalized','position', [0.08 0.3 0.08 0.6], 'callback', #(s,e) SliderCbk);
handles.Text_min = uicontrol('Style','text','String','Min','position', [60 230 40 20]);
handles.Edit_min = uicontrol('Style','edit','String',num2str(get(handles.Slider,'min')),'position', [100 230 40 20],'Callback',#(s,e) MinCallback);
handles.Text_max = uicontrol('Style','text','String','Max','position', [60 180 40 20]);
handles.Edit_max = uicontrol('Style','edit','String',num2str(get(handles.Slider,'max')),'position', [100 180 40 20]);
handles.Text_val = uicontrol('Style','text','String','value','position', [60 130 40 20]);
handles.Edit_val = uicontrol('Style','edit','String',num2str(get(handles.Slider,'value')),'position', [100 130 40 20]);
guidata(hFig,handles)
%// Callback of the edit box for the min value
function MinCallback
value_min=str2double(get(handles.Edit_min, 'String'));
if value_min > sliderValue_default
set(handles.Slider, 'Value', value_min+1);
set(handles.Slider, 'Min', value_min);
set(handles.Edit_val,'String',get(handles.Slider, 'Value'));
end
guidata(hFig,handles)
end
%// Slider callback. Just to check the value is updated correctly
function SliderCbk
CurrentValue = get(handles.Slider,'Value');
set(handles.Edit_val,'String',num2str(CurrentValue));
guidata(hFig,handles)
end
end
Screenshot of the initial GUI:
And after setting the minimum value to 5, which is above the current value of the slider:
the current value is updated to 6 as expected.
Hope that helps!

Related

How to reset the default values in a graphical user interface

I'm creating a graphic interface (manually) and I would like to have a reset button which reset the default values.
I already code this
H.but(3) = uicontrol('Units','normalized', ...
'BackgroundColor',[1 0.7 1], ...
'Callback','MyFunction(''Reset'');', ...
'FontSize',12, ...
'Position',[0.04 0.54 0.1 0.05 ], ...
'String','Reset');
case 'Reset'
clear all % Is not working and I think that isn't that I expect
set(findobj(H.fig,'style','edit', '-or','style','text'),'string','') % H is a global variable. This trial don't give the default value, it just clear certain boxes
I usually prefer to create a specific reset_gui function for my GUIs that resets all the relevant control properties (like checkbox states, strings in editable text boxes, etc.) to appropriate default values, as well as setting all relevant variable values to their defaults, clearing plots, etc..
If you'd prefer a generic option for resetting all UI control properties to their initial state, here's an example of one possible solution:
function example_reset_gui
% Initialize GUI:
hFigure = figure();
uicontrol('Style', 'edit', 'Position', [20 100 100 25]);
uicontrol('Style', 'edit', 'Position', [20 65 100 25]);
uicontrol('Style', 'push', 'Position', [20 20 60 30], ...
'String', 'Reset', 'Callback', #reset_fcn);
drawnow
% Collect default states:
[defaultState{1:3}] = get_default_state(hFigure);
% Nested reset function:
function reset_fcn(~, ~)
set(defaultState{:});
end
end
% Local function:
function [hArray, propArray, valueArray] = get_default_state(hFigure)
hArray = findall(hFigure, 'Type', 'uicontrol');
propArray = fieldnames(set(hArray(1)));
valueArray = get(hArray, propArray);
end
This creates a figure with 2 editable text boxes and a reset button. You can type whatever you want into the text boxes, and when you push the reset button it will clear them (i.e. set them to the default empty string they first contained).
The local function get_default_state will find all the uicontrol objects in the figure, then get all of their set-able properties (i.e. all properties that are not read-only), then get all the initial values for those properties. The three outputs are stored in the 1-by-3 cell array defaultState, which is accessible by the nested function reset_fcn. When the reset button is pressed, all of the set-able UI control properties are set to the values they had when first created.
It should be noted that any changes made to the Position property (such as due to resizing of the figure) could be undone by this approach. Using 'normalized' units would avoid this.
If you truly want to start your GUI over from scratch the easiest way would be to just close it open it again. You can do that from your button's callback. Which I pointed at a new function restartGUI. That could be a subfunction of your main gui or its own m-file, your choice.
Your question is pretty light on details so I can't help with some of the specifics but this should give you the general idea.
IF closing and opening isn't what your want then in the restartGUI function you would have to just manually reset the state of each of your uicontrols, etc. (whatever else is in your GUI that we can't see).
H.but(3) = uicontrol('Units','normalized', ...
'BackgroundColor',[1 0.7 1], ...
'Callback',#restartGUI, ...
'FontSize',12, ...
'Position',[0.04 0.54 0.1 0.05 ], ...
'String','Reset');
% <<<< THE rest of your code >>>
function restartGUI(hObject,varargin)
global H
close(H.fig) %Assuming H.fig the main GUI window.
%Call the GUI again which will restart it.
yourGUIFunction
Edit: added the use of the global H to close.

Manage multiple callbacks

I have made a user interface with many edit text boxes created in loops, now I want to store the user inputs in a variable with callback.
For example consider this code,
function p = myfun()
f = figure;
set(f,'Position',[200 350 250 150],'Color',[.4 .6 .4],'MenuBar','none',...
'Visible','off');
bc = [.4 .6 .4];
uicontrol('Style','text','Position',[50 80 80 30],...
'String','X','BackgroundColor',bc,'ForegroundColor','w');
uicontrol('Style','text','Position',[50 40 80 30],...
'String','Y','BackgroundColor',bc,'ForegroundColor','w');
uicontrol('style','edit','Position', [120 80 80 30],...
'BackgroundColor',bc,'ForegroundColor','w','Callback',{#My_Callback});
uicontrol('style','edit','Position', [120 40 80 30],...
'BackgroundColor',bc,'ForegroundColor','w','Callback',{#My_Callback});
uicontrol('Style', 'pushbutton', 'String', 'Ok',...
'Position', [100 5 60 30],'Callback', 'close');
movegui(f,'center')
set(f,'Visible','on')
function My_Callback(hObject,eventdata)
p = str2double(get(hObject,'string'));
end
end
Now My_Callback will be called twice but only the last one will be stored in p.
But I want them to be stored like p.x and p.y.
I think I should use Tag, it says:
Tag
string (GUIDE sets this property)
User-specified object label. The Tag property provides a means to identify graphics objects with a user-specified label. This is particularly useful when constructing interactive graphics programs that would otherwise need to define object handles as global variables or pass them as arguments between callback routines. You can define Tag as any string.
But I don't know how (I have about 16 editable boxes),
Thanks for any help.
If I understood your question correctly, you could use the UserData property of uicontrols to store the content of the edit boxes as you enter it, that way it would be very easy to recover them anywhere within your GUI or elsewhere.
Moreover, to facilitate things you can assign names to uicontrols during their creation, so when you need to get one/many of their property you can call the handles with its name instead of the hObject argument.
For example, let's say you name the box with the X data x1, then you can create and store it in the handles structure of the GUI like so:
handles.x1 = uicontrol(...)
so when you need to fetch a property, you can use
get(handles.x1,'Some Property');
So to come back to your question, you could use this syntax to set the UserData property of all the boxes inside My_Callback. Afterward you can recover them in any callback you want. Of course a simple way would be to get the String property of the edit boxes instead of their UserData, but with the latter you can store anything you want which might come handy.
In the following GUI I modified yours to change the callback for the 'OK' button for a function called DisplayData which gets the UserData from each edit box and displays it.
function p = myfun()
clear
clc
f = figure;
set(f,'Position',[200 350 250 150],'Color',[.4 .6 .4],'MenuBar','none',...
'Visible','off');
bc = [.4 .6 .4];
%//===============
uicontrol('Style','text','Position',[50 80 80 30],...
'String','X','BackgroundColor',bc,'ForegroundColor','w');
uicontrol('Style','text','Position',[50 40 80 30],...
'String','Y','BackgroundColor',bc,'ForegroundColor','w');
%//===============
handles.x1 = uicontrol('style','edit's,'Position', [120 80 80 30],...
'BackgroundColor',bc,'ForegroundColor','w','Callback',{#My_Callback});
handles.y1 = uicontrol('style','edit','Position', [120 40 80 30],...
'BackgroundColor',bc,'ForegroundColor','w','Callback',{#My_Callback});
%//===============
uicontrol('Style', 'pushbutton', 'String', 'Ok',...
'Position', [100 5 60 30],'Callback', #(s,e) DisplayData);
movegui(f,'center')
set(f,'Visible','on')
guidata(f,handles); %// Updata guidata
function My_Callback(hObject,eventdata)
p = str2double(get(hObject,'string'));
%// Assign the content of the box to its "UserData" property
set(hObject,'UserData',p)
guidata(f,handles)
end
function DisplayData(~,~)
%// You could do it for all the boxes in your GUI.
x1Data = get(handles.x1,'UserData');
y1Data = get(handles.y1,'UserData');
fprintf('The number in box 1 is %0.2f and the number in box 2 is %0.2f\n',x1Data,y1Data);
guidata(f,handles)
end
end
Sample output:
And after pressing the "OK" button, this string is displayed in the Command Window:
The number in box 1 is 2.00 and the number in box 2 is 4.00
Hope that helps!
As you mentioned in comments, you want to read your values from editbox after the "Ok" button pressed. In order to do this, you should assign your callback function to the "ok" button, not edit boxes:
uicontrol('Style', 'pushbutton', 'String', 'Ok',...
'Position', [100 5 60 30],'Callback', {#My_Callback});
In your Callback function you should read values from all your edit boxes.
I suggest you to use handles when you defined your edit boxes (and better to use it for all the objects):
e1=uicontrol('style','edit','Position', [120 80 80 30],...
'BackgroundColor',bc,'ForegroundColor','w');
e2=uicontrol('style','edit','Position', [120 40 80 30],...
'BackgroundColor',bc,'ForegroundColor','w');
Now, in order to read values, you just use handles of the corresponding edit box.
function My_Callback(hObject,eventdata)
p1 = str2double(get(e1,'string'));
p2 = str2double(get(e2,'string'));
end
Note: this handles (e1,e2) will have cyan color in your code, that means that they are "global" variables, i.e. are used in main code and callback function.
If you don't want to use global handles, you can pass them into callback function. So your callback function will have more arguments.
uicontrol('Style', 'pushbutton', 'String', 'Ok',...
'Position', [100 5 60 30],'Callback', {#My_Callback(e1,e2)});
function My_Callback(hObject,eventdata,e1,e2)
p1 = str2double(get(e1,'string'));
p2 = str2double(get(e2,'string'));
end

MATLAB Edit Text: Display more than 8 characters

I'm trying to display this number '16777215' in an Edit Text in MATLAB GUI but i end up getting this number '1.67772e+07'
This is the code for displaying the number in the textbox:
set(handles.edit7, 'string', max_count);
How can I fix this?
Thank you
I think you could sue sprintf function. For example:
mFigure = figure()
mTextBox = uicontrol('style','text', 'Position', [20 240 200 20])
set(mTextBox,'String', sprintf('%d', 16777215))
I was able to observe the same behaviour that you mentioned. When I wrapped max_count in the function to convert the number to a string, num2str, 16777215 appeared as expected:
set(handles.edit7, 'string', num2str(max_count));

How in Matlab do changes on figure 1 with slider on figure 2?

I have some sliders on figure 1, and I have some images on figure 2. I want to do the callbacks for the sliders in a way that, when I change the sliders in figure 1 , the threshold changes and images update automatically in figure 2.
I'm using addlistener to send values for callback function. The problem is when you move slider the active figure is figure 1, and you want to do changes on figure 2.
adding some code for clarification:
M.rgbImage = imread('euhedral-mag-on-po-edge-pseudo-sub-ophitic-rl-fov-4-8mm.jpg');
[rows, columns, numberOfColorBands] = size(M.rgbImage);
F.f = figure; % This is the figure which has the axes to be controlled.
% Now create the other GUI
S.fh = figure('units','pixels',...
'position',[400 400 500 100],...
'menubar','none',...
'name','Image control',...
'numbertitle','off',...
'resize','off');
S.sl = uicontrol('style','slide',...
'unit','pix',...
'position',[60 10 270 20],...
'min',0,'max',255,'val',100,...
'callback',{#sl_call2,S},'deletefcn',{#delete,F.f});
....
lis = addlistener(S.sl,'Value','PostSet',#(e,h) sl_call3(S,F,M));
function sl_call3(S,F,M)
v = get(S.sl,'value');
figure(F.f), subplot(4, 4, 13);
M.redMask = (M.redPlane > v);
imshow(M.redObjectsMask, []);
set(S.ed(2),'string',v);
Create reference to both your figures:
f1=figure(1);
f2=figure(2);
And then when doing the callback pass f2 as a parameter.
In the callback, you'll have get the handle to the second figure.
There's various ways to do that.
You can specify the handle to the second figure at the time of callback-definition:
figure2 = ...;
addlistener(hSlider, ..., #(a,b) changeStuffOn(figure2));
Or during the callback:
function callbackFunction(hObject, evt)
% get the handle to the second figure, e.g. by a tag, or its name
fig2 = findobj(0, 'type', 'figure', 'tag', 'figure2'); %
% do whatever you want with fig2
end
The latter might be somewhat worse in performance, but e.g. has the benefit of working reliably even if figure2 was deleted and recreated and some point.
To avoid the change of focus you'll have to get rid of this line your callback:
figure(F.f)
This explicitly moves the focus to the second figure.
You'll have to use e.g. the imshow(axes_handle, ...) syntax, in order to show the image not in the "current axes".

how can I get the selected value of radio button?

I am not matlab programmer but I need to create an interface using matlab!
This qusetion should be very easy for matlab programmers :)
I have an interface which contains radio button group panel "OperationPanel"
,4 radioButtons inside it which names are "addBtn, subBtn, divBtn, mulBtn" and I have command button, I want when I click over the button to get the value of the selected radioButton
What is the commad I should use ? I google it and found that if I make
get(handles.NewValue,'Tag');
I tired it but it doesn't work!! Can I hava some help!
Here's a quick example to illustrate how to get the value of a radio-button group component:
function simpleGUI
hFig = figure('Visible','off', 'Menu','none', 'Name','Calculator', 'Resize','off', 'Position',[100 100 350 200]);
movegui(hFig,'center') %# Move the GUI to the center of the screen
hBtnGrp = uibuttongroup('Position',[0 0 0.3 1], 'Units','Normalized');
uicontrol('Style','Radio', 'Parent',hBtnGrp, 'HandleVisibility','off', 'Position',[15 150 70 30], 'String','Add', 'Tag','+')
uicontrol('Style','Radio', 'Parent',hBtnGrp, 'HandleVisibility','off', 'Position',[15 120 70 30], 'String','Subtract', 'Tag','-')
uicontrol('Style','Radio', 'Parent',hBtnGrp, 'HandleVisibility','off', 'Position',[15 90 70 30], 'String','Multiply', 'Tag','*')
uicontrol('Style','Radio', 'Parent',hBtnGrp, 'HandleVisibility','off', 'Position',[15 60 70 30], 'String','Divide', 'Tag','/')
uicontrol('Style','pushbutton', 'String','Compute', 'Position',[200 50 60 25], 'Callback',{#button_callback})
hEdit1 = uicontrol('Style','edit', 'Position',[150 150 60 20], 'String','10');
hEdit2 = uicontrol('Style','edit', 'Position',[250 150 60 20], 'String','20');
hEdit3 = uicontrol('Style','edit', 'Position',[200 80 60 20], 'String','');
set(hFig, 'Visible','on') %# Make the GUI visible
%# callback function
function button_callback(src,ev)
v1 = str2double(get(hEdit1, 'String'));
v2 = str2double(get(hEdit2, 'String'));
switch get(get(hBtnGrp,'SelectedObject'),'Tag')
case '+', res = v1 + v2;
case '-', res = v1 - v2;
case '*', res = v1 * v2;
case '/', res = v1 / v2;
otherwise, res = '';
end
set(hEdit3, 'String',res)
end
end
Obviously you could add more validations on the input numbers and so on...
Have you set handles to the hOjbect? Also don't forget to update the handle after processing the radio button event. Have you looked at this Matlab GUI Tutorial? Scroll down to Part 3 step 5 to see the following example code for three radio buttons:
function fontSelect_buttongroup_SelectionChangeFcn(hObject, eventdata)
%retrieve GUI data, i.e. the handles structure
handles = guidata(hObject);
switch get(eventdata.NewValue,'Tag') % Get Tag of selected object
case 'fontsize08_radiobutton'
%execute this code when fontsize08_radiobutton is selected
set(handles.display_staticText,'FontSize',8);
case 'fontsize12_radiobutton'
%execute this code when fontsize12_radiobutton is selected
set(handles.display_staticText,'FontSize',12);
case 'fontsize16_radiobutton'
%execute this code when fontsize16_radiobutton is selected
set(handles.display_staticText,'FontSize',16);
otherwise
% Code for when there is no match.
end
%updates the handles structure
guidata(hObject, handles);
If you use this syntax below you will get an error:
get(handles.NewValue,'Tag')
What you should be using is
get(eventdata.NewValue, 'Tag')
The point is the when you are looking at the SelectionChangeFcn - what you are essentially looking for is what is the new event that has fired and what is the new value associated with that event. You don't have to use 'Tag' - you can even use 'String' or other properties that may be appropriate in your context.
the code above works on may project ..
function pushbutton_startProcess_Callback(hObject, eventdata, handles)
set(handles.edit1,'String',get(handles.edit2,'String'));
switch get(get(handles.uipanel3,'SelectedObject'),'Tag')
case 'wavelet_method', set(handles.edit1,'String','wavelet_method');
case 'glcm_method', set(handles.edit1,'String','glcm_method');
case 'ewd_method', set(handles.edit1,'String','ewd_method');
case 'wavelet_gclm_method', set(handles.edit1,'String','wavelet_glcm_method');
otherwise, set(handles.edit1,'String','boş');
end