Find handles with a specific pattern - matlab

I have some handles that look like:
ans =
figure1: 189.0205
sampleNameEdit: 17.0216
selectCatPopup: 16.0237
radiobutton_Al: 14.0266
radiobutton_O: 190.0183
output: 189.0205
How can I easily look for those handles that start with radiobutton__? In the future, I will have many more radiobuttons that I would like to retrieve easily.

To search for a specific pattern in a handle's name, the best approach would be to follow Luis Mendo's advice in his answer. However, consider searching based on the type of object you are looking for. In this case, it would seem that all radiobutton objects need to be located.
The most straightforward way to find handles of for a certain style of uicontrol, is to search for handles with their Style Property set to radiobutton. Consider a figure with two controls: a text box and a radio button, with their handles stored in an ordinary array uih:
hf = figure; % parent of uicontrols
uih(1) = uicontrol('style','text');
uih(2) = uicontrol('style','radiobutton');
Here are my test handle vales (yours will be different):
>> uih
uih =
3.0012 4.0012
The first is the text box, and the second is the radio button.
Search by parent handle
If you have the parent handle (i.e. the figure handle, hf), you don't even need the list of handles uih! Just call findobj as follows:
hr = findobj(hf,'style','radiobutton')
hr =
4.0012
Search handle array
If you don't have the parent handle, but do have a list of handles to search, that's no problem either:
hr = findobj(uih,'style','radiobutton')
hr =
4.0012
Search struct of handles
In your case, you have the handles stored as fields in a struct:
handles =
ht: 3.0012
hr: 4.0012
hr = findobj(structfun(#(x)x,handles),'style','radiobutton')
hr =
4.0012
Don't worry, this finds all radio buttons!

Assuming you have a struct with each handle stored in a different field:
s.radiobutton_1 = 1; %// example data: struct with several fields
s.otherfield = 22;
s.radiobutton_2 = 333;
names = fieldnames(s); %// get all field names
ind = strmatch('radiobutton_',names); %// logical index to matching fields
selected = cellfun(#(name) s.(name), names(ind)); %// contents of those fields
returns the desired result:
selected =
1
333

It's not really clear where you get that ans from and what its structure is, and what exactly is supposed to "start with" "radiobutton_". However, if you want to get handles to all existing radiobuttons, findobj is the way to go:
h = findobj(findobj('Type', 'uicontrol'), 'Style', 'radiobutton');
You can restrict the search to children e.g. of the current figure using
h = findobj(findobj(gcf, 'Type', 'uicontrol'), 'Style', 'radiobutton');
and you can restrict the search to a given list of handles oh (without children) using
h = findobj(findobj(oh, 'flat', 'Type', 'uicontrol'), 'Style', 'radiobutton');

Related

Tag Names As Variables And Displaying It In Matlab GUI

I’m building a GUI in Matlab (my first one), I have 160 static text boxes with the tag name “tag_matrix_1, tag_matrix_2, etc”. I’m trying to build a loop that puts all the tag names in a vector:
for i = 1:160
tagNames(i) = ['tag_matrix_' num2str(i)];
end
But I’ll always get the error: “In an assignment A(I) = B, the number of elements in B and I must be the same.”
Why? And how do I fix it?
My second question is about displaying it in a loop. Is it possible to loop it, so I don’t have 160 lines of setting up my static text boxes?
Like:
for i = 1:160
set(handles."how can I implement tagNames(i) in there",'String',data2d(i,:);
end
Rather than trying to store the tag names in an array (this will fail because they are all different sizes), I would create a struct where the fieldname is the tag name and the value is the handle itself. You can use dynamic field referencing for this.
for k = 1:160
field = ['tag_matrix_', num2str(k)];
myhandles.(field) = findobj(gcf, 'tag', field);
end
Then in your second loop (to fill in the values), you'd access the fields of this struct.
for k = 1:160
set(myhandles.(['tag_matrix_', num2str(k)]), 'String', data2d(k,:));
end
Do you actually need to store the tag_names like that? You can actually just use findobj to find the element with a given tag. This would allow you to replace the second loop with.
for k = 1:160
set(findobj(gcf, 'tag', ['tag_matrix_', num2str(k)]), 'String', data2d(k,:))
end

How to access Matlab's handle object's sub-property: 'allowedStyles'

I would like to progmatically access the 'sub-property' of a lineseries object's 'MarkerFaceColor' property called 'allowedStyles'. This 'sub-property' can be seen in Matlab's inspector, (inspect(handle)) by expanding the 'MarkerFaceColor' property row.
I would like to do something like the following or get the equivalent of such a command.
allowedstyles = get(hh,'MarkerFaceColorAllowStyles');
Screen shot of Matlab's Inspect window indicating information I seek.
https://drive.google.com/file/d/0B0n19kODkRpSRmJKbkQxakhBRG8/edit?usp=sharing
update:
For completeness my final solution for accessing this information via a cellstr was to write the following function. Thanks to Hoki.
FYI, this information (allowed styles) is useful for a GUI when you want to offer user choices for a property such as MarkerFaceColor, where you don't know the type of graphics object they are modifying. I populate a listbox with these 'allowedStyles' along with an option to set a colour. Mesh plot 'MarkerFaceColor' allows styles {'none','auto','flat'}, while a lineseries plot has {'none','auto'}.
function out = getAllowedStyles(hh,tag)
% hh - handle returned from plot, surf, mesh, patch, etc
% tag - the property i.e. 'FaceColor', 'EdgeColor', etc
out = [];
try
aa = java(handle(hh(1)));
bb = eval(sprintf('aa.get%s.getAllowedStyles;',tag));
bb = char(bb.toString);
bb(1) = []; bb(end) = [];
out = strtrim(strsplit(bb,','));
end
end
I think it is indeed ReadOnly (or at least I couldn't find the correct way to set the property, but it is definitely readable.
You need first to access the handle of the underlying Java object, then call the method which query the property:
h = plot([0 1]) ; %// This return the MATLAB handle of the lineseries
hl = java(handle(h)) ; %// this return the JAVA handle of the lineseries
allowedstyles = hl.getMarkerFaceColor.getAllowedStyles ; %// this return your property :)
Note that this property is actually an integer index. Your inspect windows translate it to a string saying [none,auto] while in my configuration even the inspect windows only shows 1.
If you want the exact string translation of other values than one, you can call only the parent method:
hl.getMarkerFaceColor
This will display the allowed style in plain text in your console window.
ans =
com.mathworks.hg.types.HGMeshColor#28ba43dd[style=none,allowedStyles=[none, auto],red=0.0,green=0.0,blue=0.0,alpha=0.0]
If you insist on getting this property as a string progamatically, then you can translate the above using the toString method.
S = char( hl.getMarkerFaceColor.toString )
S =
com.mathworks.hg.types.HGMeshColor#1ef346e8[style=none,allowedStyles=[none, auto],red=0.0,green=0.0,blue=0.0,alpha=0.0]
then parse the result.

Within Matlab GUI, I want to transfer the selected data in listbox1 to listbox2

This case is, I know how to transfer all the data from one listbox to another one, and then clear listbox1. I did in this way:
function pushbutton1_Callback(hObject, eventdata, handles)
StringInLB1 = get(handles.listbox1,'string');
set(handles.listbox2,'string',StringInLB1);
set(handles.listbox1,'string','');
Now my question is: How can I transfer some selected data to listbox2 ? I "ctrl+ single click" multiple data in listbox1, but how can I use thoes data?
Thanks a lot.
It looks like you are looking to assign some function to the listbox callback. i.e. each time the selection is changed by the user, you want to do something with the data. Anyhow that's what I understood from your comment to #James answer.
If it's the case, here is a sample code generating a simple GUI in which the color of a plot is changed by the user directly by clicking in the listbox:
function DummyListBox
global hFig hListBox hPlot
ScreenSize = get(0,'ScreenSize');
hFig = figure('Visible','off','Position',[ScreenSize(3)/2,ScreenSize(4)/2,450,285]);
ColorString = {'Red';'Green';'Blue'}; % Define string populating the listbox
hListBox = uicontrol('Style','Listbox','String',ColorString,'Position',[315,150,70,50],'max',3,...
'min',1,'Callback',#ListBox_Callback); %%// added 'min' and 'max' properties to select multiple items
hText = uicontrol('Style','Text','Position',[315,220,70,35],'String','Empty now'); %%// Add text box
hAxes = axes('Units','Pixels','Position',[50,60,200,185]);
set(hFig,'Visible','on')
x = 1:5*pi;
hPlot = plot(x,sin(x),'-r','Parent',hAxes); %display some data
% Listbox callback: each time the selection changes, the color of the
% plot changes accordingly.
function ListBox_Callback(~,~)
SelectedValues = get(hListBox,'Value'); % Get the values selected
set(hText,'String',SelectedValues); % Uptdate the string in the textbox
NewColor = ColorString{get(hListBox,'Value')};
set(hPlot,'Color',NewColor)
end
end
The output now looks like this:
As you see the function in which the change in color takes place is the listbox's callback. Hope this is what you want. If not please be more specific as to what you would like. Thanks!
EDIT: As you can see, I added a text box to show you what it looks like when you select multilpe items in the listbox. In order to do so, you must add a 'min' and a 'max' property when you create the listbox. I set them to 1 and 3, respectively. The 'Value' property of the listbox corresponds to the actual number of the item selected from the list. So if you have 3 items as is my exmample,the Value can be 1,2,3 or any combination. They are displayed in the text box. You can get the corresponding data from those values, stored in vectors.
So to answer your question, you could write:
Data1 = ValuesVector(1)
Data2 = VectorValues(2)
... and so on
If you use a
tmp = get(handles.listbox1,'string');
You'll see what the variable is like. Then you can use something like
set(handles.listbox1,'string',tmp{2});

Save multiple GUIdata sets to listbox and then load them again in MATLAB

I have built a calculation software in MATLAB GUIDE. What I want to do is to fill out all my calculation data in different edit fields and some dropdowns and when I press calculate a "listbox" should be populated with the text "Calculation 1".
If I then change some data in some of the input fields and press calculate again I want to populate the listbox with "Calculation 2" beneath "Calculation 1" etc...
But then I would want to be able to highligt "calculation 1" again in the listbox and press a "load input parameters" button to populate all the edit input fields with the data that was used when "calculation 1" was calculated.
I have looked all over the place for this but can't find anything.
//Robin
Here is some code which is very basic but performs what you are looking for. There are a lot of tweaks possible but I'll let you play around with them. I put explanations as comments. You can copy past into Matlab and change the GUI as you like.
function CalculatorGUI
% Dummy GUI to calculate A*B + C...
clc
clear
close all
global hTestResult hEditA hEditB hEditC CalculationList CalculationStrings
% Set up controls
CalculationList = nan(10,3); % Create array in which we store the parameters. 1st column is A, 2nd is B and 3rd is C.
CalculationStrings = cell(10,1);
ScreenSize = get(0,'ScreenSize');
hFig = figure('Visible','off','Position',[ScreenSize(3)/2,ScreenSize(4)/2,450,285]);
hCalculateButton = uicontrol('Style','Pushbutton','Position',[350,150,80,30],'String','Calculate!','Callback',#CalculateCallback);
hTitle = uicontrol('Style','Text','Position',[100,250,100,25],'String','Calculate (A * B) + C');
hTextA = uicontrol('Style','Text','Position',[125,220,70,25],'String','A');
hEditA = uicontrol('Style','Edit','Position',[125,200,70,25],'String','1');
hTextB = uicontrol('Style','Text','Position',[200,220,70,25],'String','B');
hEditB = uicontrol('Style','Edit','Position',[200,200,70,25],'String','2');
hTextC = uicontrol('Style','Text','Position',[275,220,70,25],'String','C');
hEditC = uicontrol('Style','Edit','Position',[275,200,70,25],'String','3');
hResultHeader = uicontrol('Style','Text','Position',[350,220,70,25],'String','Result');
hTestResult = uicontrol('Style','Text','Position',[350,200,70,25],'String','');
hTextCalcu = uicontrol('Style','Text','Position',[100,140,100,50],'String','Calculations');
hListCalcu = uicontrol('Style','Listbox','String','','Position',[100,120,200,50],'max',10,...
'min',1,'Callback',#ListBox_Callback);
set(hFig,'Visible','on')
%======================================================================
%======================================================================
% Callback of the pushbutton
function CalculateCallback(~,~)
% Get the values in the edit boxes. There is no ckechup to make
% sure the user entered a correct value...
A = str2double(get(hEditA,'String'));
B = str2double(get(hEditB,'String'));
C = str2double(get(hEditC,'String'));
Calculation = A*B+C;
% Display the result.
set(hTestResult,'String',sprintf('The result is %0.2f',Calculation));
% Find how many calculations have been performed and append the
% parameters to the current list
[x,~] = find(~isnan(CalculationList));
CurrentCalc = numel(unique(x)); % Get number of rows which are NOT NaNs.
CurrentValues = [A B C];
CalculationList(CurrentCalc+1,:) = CurrentValues;
CurrentString = sprintf('A = %0.2f B = %0.2f C = %0.2f',A,B,C);
% Assign the parameters to the cell array.
CalculationStrings(CurrentCalc+1) = {CurrentString};
set(hListCalcu,'String',CalculationStrings)
end
% Listbox callback: When the selection changes, the corresponding
% parameters in the edit boxes change.
function ListBox_Callback(~,~)
SelectedCalc = get(hListCalcu,'Value');
CalculationList(SelectedCalc,1)
CalculationList(SelectedCalc,2)
CalculationList(SelectedCalc,3)
set(hEditA,'String',CalculationList(SelectedCalc,1));
set(hEditB,'String',CalculationList(SelectedCalc,2));
set(hEditC,'String',CalculationList(SelectedCalc,3));
end
end
The actual interface looks like this:
Of course you can make it much more complex, but this should help you get started and understand how the different callbacks work together. Have fun!

How to get all data from a struct?

I've got a result from a web service and MatLab gladly notifies that it is a 1x1 struct. However, when I try to display it (by typing receivedData and pressing enter) I get to see this:
ResponseData: [5x1 struct]
Equally gladly, I entered the following, in my attempt to get the data viewed to me:
struct2array(responseData)
I get only a bunch (not five, more than five) of strings that might be names headers of columns of the data provided.
How do I get all the data from such structure?
You may use fieldnames to get the data from the struct and then iteratively display the data using getfield function. For example:
structvariable = struct('a',123,'b',456,'c',789);
dataout = zeros(1,length(structvariable)) % Preallocating data for structure
field = fieldnames(a);
for i = 1:length(structvariable)
getfield(structvariable,field{i})
end
Remember, getfield gives data in form of cell, not matrix.
or you can use cellfun function:
% STRUCT - your structure
% tmp_nam - structure field names
% tmp_val - values for structure field names
tmp_nam = fieldnames(STRUCT);
tmp_val = cellfun(#(x)(STRUCT.(x)),tmp_nam,'UniformOutput',false);
In order to display all elements and subelements of a structure there is a custom function that you can download here:
http://www.mathworks.com/matlabcentral/fileexchange/13831-structure-display
Some useful access syntax:
someVar = ResponseData(1) %Displays the first element
someVar = ResponseData(4) %Displays the 4th element
To display them all, one after the next
for ix = 1:length(ResponseData)
tmp = ResponseData(ix);
end
To get all the fieldnames
names = fieldnames(ResponseData)
To get all 5 data elements from the structure with the first field names, and put them into a cell array
ixFieldName = 1;
someCellArray = { ResponseData.(ixFieldName{1}) }
A small correction to Sahinsu's answer:
structvariable = struct('a',123,'b',456,'c',789);
dataout = zeros(1,length(structvariable)) % Preallocating data for structure
field = fieldnames(structvariable);
for i = 1:length(field)
getfield(structvariable,field{i})
end