Values of selected item in list box moved into a struct
You are now following this question
- You will see updates in your followed content feed.
- You may receive emails, depending on your communication preferences.
An Error Occurred
Unable to complete the action because of changes made to the page. Reload the page to see its updated state.
Show older comments
0 votes
Share a link to this question
i have created an empty struct, how do i move the values of the selections made in a list box into a struct. Usually this is created in matrix in matlab when you run the code in the command window, but for app designer is seems different.
I have attached a the code generated from App designer for one of my list box.
How do i make the current selection or what even selection made appear in an already created struct. i have also include the code for the empty struct.
properties (Access = public)
myStruct = struct()
end
% Create ListBox
app.ListBox = uilistbox(app.AgeTab);
app.ListBox.Items = {'18-28', '29-39', '40-50', '51-61', '62-72', '73-83'};
app.ListBox.ValueChangedFcn = createCallbackFcn(app, @ListBoxValueChanged, true);
app.ListBox.FontName = 'Arial Black';
app.ListBox.FontSize = 24;
app.ListBox.FontColor = [0.3922 0.8314 0.0745];
app.ListBox.BackgroundColor = [0.502 0.502 0.502];
app.ListBox.Position = [40 350 795 169];
app.ListBox.Value = '18-28';
% Create GenderTab
app.GenderTab = uitab(app.TabGroup);
app.GenderTab.Title = 'Gender';
app.GenderTab.BackgroundColor = [0.502 0.502 0.502];
Accepted Answer
Voss
on 22 Nov 2022
The code above creates and initializes a couple of components (a uilistbox and a uitab). Those components are stored in the app object, and anything you need to know about those components, you can get at any time.
For instance, the expression
app.ListBox.Value
returns the Value of app.ListBox at the time the command is run.
Generally, there is no need to create a separate data structure mirroring the state of a GUI; you can simply get the state of the GUI at any time.
What are you trying to accomplish by making a separate struct that mirrors the GUI state (if that is in fact the intention)?
(Having said that, assuming you have a good reason to do this, you can keep your struct up to date by updating it in the callbacks of your components.)
15 Comments
Nwasinachi
on 22 Nov 2022
"What are you trying to accomplish by making a separate struct that mirrors the GUI state (if that is in fact the intention)"?
The GUI will be ran at least 50 times and there are several inputs that i need to save.
Also the inputs will be different time the GUI is ran.
For example.
i can compare language proficieny and how well the perfomance was on the cognitive test.
Does this make sense. I feel like sometimes i might over explain and it sounds redundant.
If I understand correctly, there is no need to store a data structure which needs to be updated whenever the user makes a selection in the GUI. What you can do instead is to save the GUI state (or the relevant properties from the GUI) one time when the program is closed. To do that, define a CloseRequestFcn, which will grab the things you need (e.g., app.ListBox.Value, app.ListBox_3.Value, etc.) and save them to a mat file (or other type of file). Then you have the selections made by that user and you can use that mat file in your post-analysis.
If each user might run the program multiple times, you can check if your mat file already exists before saving, and if so give it a different name, or better: name the file with a time-stamp so you know when the data was collected, or better yet: use a time-stamp and a user ID. (Or simply append the selections made in each new run to the existing mat file.)
Would that be sufficient for your purpose? Or do you also need to be able to initialize the GUI into a particular state, which may vary?
Nwasinachi
on 22 Nov 2022
So something along this line. Would there be a better and more sophisticated way to go about this?
Creating a loop that allows the file to save with a different user id from 1-50, and then deleting the app at the end, or maybe the app shouldnt be deleted because it might run the whole code together and the informtion would be lost.
% Close request function: UIFigure
function EXITButtonPushed(app, event)
userID=50 % number of files that will be created
for i=1:userID % loop that creates new file everytime the exit button is pushed
save('userID.mat',app.ListBox.Value,app.ListBox_3.Value,app.ListBox_4.Value,'-mat')
%set(,'CloseRequestFcn','my_closereq')
end
app.delete % deletes the app
end
Voss
on 23 Nov 2022
I guess I'm confused about why you would save the same information 50 times. I thought the idea was that different users would be running separate instances of the app, in which case you could save their selections when they are done (e.g., when they close the app).
Nwasinachi
on 23 Nov 2022
Moved: Voss
on 23 Nov 2022
it wouldnt be the same infomation 50times it will 50 different users. i just wanted to be able to auto generate a user ID. So everytime the EXIT button is pressed it assign a different ID.
Voss
on 23 Nov 2022
I suggested using user IDs because I thought you'd have each user running the program multiple times. The idea was that you'd need to know which user generated which datasets, in order to do the post-analysis properly.
Can you explain what is the actual situation you'll be using this program in (i.e., how many users, how many runs per user, whether it's important to know which user generated which data, etc.)?
Nwasinachi
on 23 Nov 2022
The users will not be using the program multiple times.
They will start the program listen to some audio and anwser yes or no to a question. There will be correct and incorrect answers, but making a counter isnt very difficult.
it will be 50-100 users, 1 run per user.
it is important to know which user generated a data set. I can merge all the mat files and then analyze it aftewards.
OK, in that case, you can create one mat file each time a user is done with the app. You can generate the mat file name based on the current time, since you know that you'll never get the same name twice (unless this is running on more than one machine and two users might finish at the same time, in which case you'd need some other identifier in the file name as well, such as a machine ID).
Maybe something like this:
function EXITButtonPushed(app, event)
file_name = sprintf('%s.mat',datetime(now(),'ConvertFrom','datenum','Format','yyyy_MM_dd_HH_mm_ss_SSS'));
selections = { ... % TBD: include all settings you want to save here
app.ListBox.Value ...
app.ListBox_3.Value ...
app.ListBox_4.Value ...
};
save(file_name,'selections');
app.delete % deletes the app
end
I recommend NOT using that function as the uifigure's CloseRequestFcn but only as the EXITButton callback, because the user could close the app before finishing and presumably you don't want to save the settings in that case - you only want to save complete datasets. In fact, it might be a good idea to prevent the user from closing the app (other than with the EXIT button), by setting the CloseRequestFcn to some function that does nothing, e.g.:
% Close request function: UIFigure
function do_nothing(~,~)
% do nothing. don't close the app. do nothing.
end
Nwasinachi
on 28 Nov 2022
@Voss Thank you so much, all of your solution have worked.
I do have one last question.
Is it possible to randomize the text displayed in a textarea in app designer?
I have tried it as a textarea. Now i am trying an Editfield, but the entire field is empty after the code is ran
changingValue = event.Value;
firstopt=sprintf('The boy went to school')
Secoption=sprintf('The man went to church')
thoption=sprint('The girl is going there')
wordarray= {firstopt Secoption thoption};
Randomization=randperm(length(wordarray));
end
end
Voss
on 28 Nov 2022
Be sure to index wordarray with Randomization, and set the result as the Value of the uitextarea, i.e.:
firstopt = 'The boy went to school'; % no need for sprintf here
Secoption = 'The man went to church';
thoption = 'The girl is going there';
wordarray = {firstopt Secoption thoption};
Randomization = randperm(length(wordarray));
% showing the random indices, for reference:
Randomization
Randomization = 1×3
1 3 2
% showing what will be in the textarea, for reference:
wordarray(Randomization)
ans = 1×3 cell array
{'The boy went to school'} {'The girl is going there'} {'The man went to church'}
% update the UI:
app.my_textarea.Value = wordarray(Randomization)
(The documentation states that the text in a uieditfield is displayed as a single line, so in order to get multiple lines of text, you should use a uitextarea.)
Nwasinachi
on 28 Nov 2022
Edited: Nwasinachi
on 28 Nov 2022
@Voss It worked, but the only issue is that it is displaying all three rather than just one at a time.
Voss
on 28 Nov 2022
To display a random character vector among firstopt, Secoption, thoption:
firstopt = 'The boy went to school'; % no need for sprintf here
Secoption = 'The man went to church';
thoption = 'The girl is going there';
wordarray = {firstopt Secoption thoption};
app.my_textarea.Value = wordarray{randi(numel(wordarray))}
Nwasinachi
on 29 Nov 2022
@Voss Why do you think it is saying the wordarray is undefined?
%attempt for text area Question 1
Correct=0;
Incorrect=0;
firstopt = 'The boy went to school'; % will change text and number of the
Secoption = 'The man went to church';
thoption = 'The girl is going there';
wordarray = {firstopt Secoption thoption};
app.TextArea7_2.Value = wordarray{randi(numel(wordarray))}; %% randomization works.
function ListBox2ValueChanged(app, event)
value = app.ListBox2.Value;
if strcmp(app.ListBox2.Value,'YES')||strcmp(app.ListBox2.Value,'NO');
set(app.NEXTButton_7,'Enable','on');
end
% This is giving me an error saying wordarray is an undefined variable, but
% i have clearly defined it in the code above.
if app.TextArea7_2.Value==wordarray{1} && app.ListBox2.Value =='YES';
Correct = Correct+1;% a loop where if this option is displayed and YES is selected from list box then the response is correct
else Incorrect = Incorrect+1;
end
Voss
on 29 Nov 2022
Each function has its own workspace, so ListBox2ValueChanged doesn't know about wordarray because wordarray is defined inside another function.
In an app, you can make a variable an app property and define it in the startup function so that it can be seen by all functions in the app. You can do that for wordarray by including this in your startup function:
firstopt = 'The boy went to school'; % will change text and number of the
Secoption = 'The man went to church';
thoption = 'The girl is going there';
app.wordarray = {firstopt Secoption thoption};
and refer to app.wordarray instead of wordarray everywhere.
Nwasinachi
on 29 Nov 2022
Edited: Nwasinachi
on 29 Nov 2022
@Voss i set wordarray as a variable in the property
properties (Access = public)
wordarray % Description
end
Changed it to app.wordarray everywhere that i need it.
%attempt for text area Question 1
Correct=0;
Incorrect=0;
firstopt = 'The boy went to school'; % will change text and number of the
Secoption = 'The man went to church';
thoption = 'The girl is going there';
app.wordarray = {firstopt Secoption thoption};
app.TextArea7_2.Value = app.wordarray{randi(numel(app.wordarray))}; %% randomization works.
But this line is still giving me an error. i have used app.wordarray{firstopt} which it stated that it wasnt a defined variable. Do i need to add that variable into the properties as well?
if app.TextArea7_2.Value==app.wordarray{1} && app.ListBox2.Value =='YES';
Correct = Correct+1;% a loop where if this option is displayed and YES is selected from list box then the response is correct
else Incorrect = Incorrect+1;
end
More Answers (0)
Categories
Find more on Whos in Help Center and File Exchange
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!Select a Web Site
Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .
You can also select a web site from the following list
How to Get Best Site Performance
Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.
Americas
- América Latina (Español)
- Canada (English)
- United States (English)
Europe
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)