MATLAB Answers

0

Package app with multiple GUIs

Asked by Rafael Félix Soriano on 5 Feb 2019
Latest activity Commented on by Li Mun Ng on 28 Aug 2019
Hi have coded an app that employs several UI figures as well as multiple functions, and I would to package it to a mlapp.install file. To do so, I open the starting app in the App Designer, click on "Share", "Matlab App". As the main file I have said app and, as the dependency analysis does not return any files, I include all the other apps and functions on shared resources. However, once I have installed the app and run it, it does not find any of the apps or functions that were included in shared resources.
It has to be a Matlab App, not a standalone program. Thank you.

  2 Comments

How do you reference the fig files in your code? Can you attach a zip file of your files? Much easier to debug that way.
TA1 is the starting app, entered as main file in the package

Sign in to comment.

4 Answers

Answer by Cris LaPierre
on 6 Feb 2019
 Accepted Answer

After a lot of digging around, here's my final answer.
  1. Files are not being identified automatically because the app names are strings. Remove the run commands and just call the apps by name.
  2. Do not delete the main app. This clears the app files from the path, breaking the app. Instead, change the visibility of TA1 ('on' and 'off'). You can delete the supporting apps as you do. It is just the main app that must persist.
  3. To change the visibility, create a public function in TA1 that sets the visibility on or off. Other apps will be able to access this function.
  4. For the function to work, you must pass in the app structure of TA1 as the first argument. Use this documentation page as an example of how to do that. Basically, add an input argument to all the apps that can connect back to TA1 (TA2, TA3, TA4, TA12, TA13, TA14, TA15). We can name the input mainapp. We also need to add a property to these apps - name it CallingApp - as well as the following to the startupFcn: app.CallingApp = mainapp;
I created a public function called TA1Visible to hide TA1 if val is 0, and otherwise show it.
methods (Access = public)
function TA1Visible(app,val)
switch lower(val)
case {0,'false','no'}
app.InicioAvion.Visible = 'off';
otherwise
app.InicioAvion.Visible = 'on';
end
end
end
To call this function from within TA1, I'd do the following (to hide TA1 and show the next mlapp). Note that I am passing app as an input when calling TA12. This gets assigned to app.CallingApp in TA12. The next step shows why.
% Button pushed function: SeleccionaravinButton
function SeleccionaravinButtonPushed(app, event)
TA1Visible(app,0);
TA12(app)
end
To call this function from outside TA1, I'd do the following (to delete TA12 and show TA1). Note that now I call TA1Visible with app.CallingApp as input, or the original app structure of TA1.
% Button pushed function: VolverButton
function VolverButtonPushed(app, event)
TA1Visible(app.CallingApp,1)
delete(app)
end
To maintain access to the public function in TA1, and ultimately the visible property of TA1, we need to maintain access to the app structure of TA1. Therefore, we need to pass app.CallingApp as input to all mlapps that have a pathway of returning the user to TA1. This is how I would call TA3 from TA2, since TA3 can return the user to TA1.
% Pasamos a la siguiente ventana
TA3(app.CallingApp)
delete(app)
In TA3, app.CallingApp gets assigned to mainapp, which in turn gets assigned internally to app.CallingApp. Then, if the user clicks on 'Volver' in TA3, the callback can return them to TA1:
% Button pushed function: VolverButton
function VolverButtonPushed(app, event)
TA1Visible(app.CallingApp,1)
delete(app)
end
That's a lot to follow, so I'm also attaching the modified files.

  1 Comment

It seems to work perfectly, thank you so much.

Sign in to comment.


Answer by Cris LaPierre
on 6 Feb 2019
Edited by Cris LaPierre
on 6 Feb 2019

This is more complicated than I was hoping, but it does boil down to a path issue. The files no longer exist in the current folder or the path. When an app is installed, the default location in Windows is "...\Documents\MATLAB\Add-Ons\Apps". However, even that can't be guaranteed since users can change this location in their Preferences.
For some basic getting started info, this is a good page to read.
Removing the run command and calling the apps by name does cause the different app files to be autodetected when packaging. However, it's going to be more complicated than that. It's throwing other errors now.

  6 Comments

Sorry, I forgot to add the functions as well as the apps to the zip file. Here it is.
Ok, I'm starting to get somewhere. The main issue I'm encountering is that when you delete the mainapp, all path information is lost. Rather than delete, consider hiding. I've just been testing going back and forth between TA1 and TA12.
In TA1, do the following:
% Button pushed function: SeleccionaravinButton
function SeleccionaravinButtonPushed(app, event)
app.InicioAvion.Visible = 'off';
TA12(app)
end
In TA12, we need to use the advice given here to be able to make TA1 visible again. Using the same variable names, add an input called mainapp. Add a private property called CallingApp. In the startupFcn, place the following code:
app.CallingApp = mainapp;
Modify VolverCallback as follows:
% Button pushed function: VolverButton
function VolverButtonPushed(app, event)
app.CallingApp.InicioAvion.Visible = 'on';
delete(app)
end
That's as far as I've gotten, but now if I package everything and install it, I can go back and forth between TA1 and TA12 without any errors. Figured that might be enough to get you started. I haven't checked what happens at the next level yet.
I can´t seem to make it work. I´ve done what you indicate, but it still returns errors. I attach the modified apps TA1, TA2 and TA12, maybe I missed something.

Sign in to comment.


Answer by Li Mun Ng on 22 Aug 2019

Good day.
May I know which version of MATLAB are you using? It is because I am experiencing the same issue too with the multiple apps to be combined together. I was unable to open the file uploaded here due to the different version of MATLAB.

  2 Comments

I believe these files were created in 2018b. What version are you using?
Thank you Criis for your answer. My version is 2017b and that's why I was unable to open the file. As I am having issue with the multiple apps to be linked together.

Sign in to comment.


Answer by Li Mun Ng on 25 Aug 2019

Good day. I have tried using the similar way as the above to combine all the .mlapp but seems something went wrong.
I have a user interface where MainApp is the home page and it has three sub app. Then in each of the sub app, it will link to another two sub app.
However, I can't seem to make it right.
I have done the following:
(1) Startup Fcn: To add the input argument in all the apps. The input argument is only ''mainapp" as the apps do not share any data in between. Howevr, the error detected was:
Cannot run with provided input arguments.
Caused by:
Not enough input arguments.
(2) In the MainApp, Private Property has been created to store the other apps.
properties (Access = private)
TypeAApp % Sub App
TypeBApp % Sub App
TypeCApp % Sub App
end
(3) In the sub app, Private Property has been craeted to call the main app.
properties (Access = private)
CallingApp % Main app object
end
(4) The button in TypeA App, TypeB App and TypeC App is used to return to the MainApp.
% Button pushed function: HOMEButton
function HOMEButtonPushed(app, event)
MainAppVisible(app.CallingApp)
delete(app)
end
(5) Meanwhile, the button in TypeA1 App and TypeA2 App is used to return to the TypeA App. However, I have no idea how to link back to only Type A1 App by using the CallingApp = mainapp as it has been used for the MainApp which serves as home page.
(6) Drop Down is used in the MainApp to allow the user to choose which type to proceed to the desired testing. The code used is defined in such a way:
function CategoryDropDownValueChanged(app, event)
value = app.CategoryDropDown.Value;
app.TypeAApp = TypeA(app);
app.TypeBApp = TypeB(app);
app.TypeCApp = TypeC(app);
%If Type A is selected, show TypeA App
if strcmp(value,'Type A')
app.TypeA.Visible = 'on';
elseif strcmp(value,'Type B')
app.TypeB.Visible = 'on';
elseif strcmp(value,'Type C')
app.TypeC.Visible = 'on';
end
I have attached the code in zip file. As I have been trying to troubleshoot but to no avail.

  4 Comments

Show 1 older comment
Thank you Cris for the assistance. I have tried applying the codes in the converted file into my standalone app however issue still occurs as it's like hairwired to me.
I couldn't even make one button function which frustrating me.
The Main App is linked to TypeA app, TypeB app and TypeC app, however when I tried to simulate it, the warning message shows:
Error using TypeA
Too many input arguments.
All the three buttons were not responding and received the same error as above.
Then, the sub app in TypeA, which are TypeA1 and TypeA2 (The user can choose to return to TypeA app or proceed to TypeA2 app), I make both sub apps to only can return to TypeA app, not the MainApp, however, again, it has got error where the problem is the CallingApp as I already defined in the MainApp. So how to distinguish between the MainApp and the TypeA (TypeB and TypeC as well because the process will be the same).
The code that I used is attached below.
I think you are getting the error because your startup function is trying to call an undefined variable, mainapp. Remember functions only have access to the variables that are passed in or created inside the function. Your startup function should look like this:
function startupFcn(app, mainapp)
app.CallingApp = mainapp;
end
Luckily, R2017b is the release where the ability to add input arguments to a function was added. Follow the instructions in step 1 here.
In the sample code I uploaded, the code in TA2 has errors. Use TA3 instead. In short, your ReturntoMain function should look like this
function ReturntoMainAppButtonPushed(app, event)
MainAppVisible(app.CallingApp,1)
delete(app)
end
Take note of the warnings in your MainApp file - your mlapp files and buttons share the same names. Best to give them each a unique name.
Map out all possible paths between the apps. Any path that has the ability to return to MainApp must keep track of mainapp. In the sample files I shared, look at the path of TA1 > TA2 > TA3 > TA4 > TA3 > TA1.
Thank you Cris once again. It was working fine after several trials and errors. I appreciate your kind assistance. Good day!

Sign in to comment.