GUI by code dynamic

3 visualizaciones (últimos 30 días)
Elando
Elando el 20 de Mayo de 2016
Editada: Elando el 2 de Jun. de 2016
Hi,
I'm a beginner in creating GUI by code and I want to create something dinamic. I've create a excel file where I put all the property of the object that I have to plot in the GUI and then by code I create them because at the end they are going to be several object and I don't want to create il all manually one by one.
In the code I have put a condition that recognize the type of object and plot it with his specific property, but I can't make the same with the parent option. What do I have to put where there are the ???
Thank you Here is the code and the excel table:
switch Values{g,ind(2)} % rileva la tipologia dell'oggetto
case 'figure'
eval([Values{g,ind(3)} '= figure(''Name'',Values{g,ind(5)},''Position'',[Values{g,ind(6)} Values{g,ind(7)} Values{g,ind(8)} Values{g,ind(9)}])'])
case 'tab_group'
eval([Values{g,ind(3)} '= uitabgroup(''Parent'', ???,''Position'',[Values{g,ind(6)} Values{g,ind(7)} Values{g,ind(8)} Values{g,ind(9)}])'])
end
  1 comentario
Stephen23
Stephen23 el 23 de Mayo de 2016
Using eval to access these variables is going to be very buggy and slow to run, as has been explained many times on this forum:
A much more robust solution would be to use a structure to store the data.

Iniciar sesión para comentar.

Respuesta aceptada

Stephen23
Stephen23 el 23 de Mayo de 2016
Editada: Stephen23 el 23 de Mayo de 2016
This is a classic example of how using eval makes code so obfuscated. Beginners often seem to think that using eval solves problems, but it really just makes the code hard to follow, buggy, and slow to run. Time to do some reading about eval:
The basic problem is: how to define the parent figure handle when the parent figure handle is dynamically defined? The best solution is: don't!
Here is a working example of how to use a structure to achieve something like what you seem to want, without using evil eval at all:
% read file data:
[~,~,raw] = xlsread('temp.csv');
% convert to structure:
C = raw(1,:);
C(2,:) = num2cell(raw(2:end,:),1);
S = struct(C{:});
% create graphics objects:
for k = 1:numel(S)
pos = [S(k).x,S(k).y,S(k).w,S(k).h];
S(k).position = pos;
switch S(k).type
case 'figure'
S(k).handle = figure('Name',S(k).name,...
'Units',S(k).units, 'Position',pos);
case 'uipanel'
S(k).handle = uipanel('Parent',S(1).handle,...
'Units',S(k).units, 'Position',pos);
otherwise
error('Sorry, but %s is not supported.',S(k).type)
end
end
You will find all of the file data and handles clearly listed in the structure S: because a structure is used each field can be easily accessed using its fieldname (which is much more robust than using indexing into a cell array). This also means that you can change the order of the columns in the file, or add new columns of information if you wish to, and the code will keep working, as long as the fieldnames are the same.
You can also access the field values of the structure very easily:
Note that in this example I have just one figure and defined it first: if you have multiple figures or nested graphics objects then you will need to manage those handles in some way to refer to them and track them correctly. Such a scheme is beyond the scope of this question (or my answer) because it depends entirely on how complicated your UI will be. Something to think about though.
By the way, my code creates this figure:
Because you did not provide us with any sample data file I created my own text file with some figure parameters. You can find it here:
  2 comentarios
Elando
Elando el 27 de Mayo de 2016
Thank you very much, you helped me a lot. I used eval because it was the first thing that I found, but with your suggestion is better.
Elando
Elando el 2 de Jun. de 2016
Editada: Elando el 2 de Jun. de 2016
Now I have another question; after I defined all the element of the GUI how can I call the callback function of all the elements? In the example I would like to call the callback when the user push the button in the GUI.
if true
% code
% read file data:
[~,~,raw] = xlsread('dates.csv');
% convert to structure:
C = raw(1,:);
C(2,:) = num2cell(raw(2:end,:),1);
S = struct(C{:});
% create graphics objects:
for k = 1:numel(S)
pos = [S(k).x,S(k).y,S(k).w,S(k).h];
S(k).position = pos;
switch S(k).type
case 'figure'
S(k).handle = figure('Name',S(k).name,...
'Units',S(k).units, 'Position',pos);
case 'uipanel'
S(k).handle = uipanel('Parent',S(1).handle,...
'Units',S(k).units, 'Position',pos);
case 'push'
S(k).handle = uicontrol('Parent',S(2).handle, ...
'Style','pushbutton', ...
'Callback',str2func(S(k).name), ...
'Units',S(k).units, 'Position',pos);
otherwise
error('Sorry, but %s is not supported.',S(k).type)
end
end
end

Iniciar sesión para comentar.

Más respuestas (1)

Geoff Hayes
Geoff Hayes el 23 de Mayo de 2016
Elando - using eval is generally discouraged as it leads to code that is difficult to trouble shoot whenever a bug arises. In this case, I understand why you are doing it this way as you are trying to build a GUI from an Excel file that you can presumably make changes to and then run your code that will build the newly designed GUI.
So, the parent of your tgroup is Main_fig, or Values{g,ind(4) which you should be able to use in place of the ??? in the above code.
  1 comentario
Elando
Elando el 23 de Mayo de 2016
Editada: Stephen23 el 23 de Mayo de 2016
Geoff Hayes - thank you for your answer. Yes, the idea was to create the GUI by Excel because at the end the GUI will have many elements and with a source structure I can manage better the changes.
I used eval because it was the only solution that I found; do you have any suggest to do it in another way?
In the tgruop the parent should be the element in the fourth column of the Excel file that in this case should recall the Main_fig.
Here is the complete code that I make:
[~,~,Values] = xlsread('GUI_info');
Values = Values(2:end,:);
Values(strcmp(Values(:,1), '%'), :) = [];
Values = sortrows(Values,1);
[row_mat,col_mat] = size(Values);
for g = 1:row_mat
for t = 1:col_mat
if isnan(Values{g,t})
Values{g,t} = [];
end
end
switch Values{g,2}
case 'figure'
eval([Values{g,ind(3)} '= figure(''Visible'', ''off'', ''NumberTitle'', ''off'', ''Name'', Values{g,5}, ''Units'', ''centimeter'', ''Position'', [Values{g,6} Values{g,7} Values{g,8} Values{g,9}])'])
case 'tab_group'
eval([Values{g,ind(3)} '= uitabgroup(''Parent'', ???, ''Units'', ''centimeter'', ''Position'', [Values{g,6} Values{g,7} Values{g,8} Values{g,9}])'])
end
end

Iniciar sesión para comentar.

Categorías

Más información sobre Data Import from MATLAB en Help Center y File Exchange.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by