Start App from file storing settings and load them at startup - matlab

I'm working on an App in app designer. Within the app the user will select a bunch of options before running some calculations.
To simplify this process I added a "Save as..." menu so that the user can save the current settings to a file (.mat) and reload them when they open the app the next time.
What I'm trying to achieve is that the user can double click on the previously saved .mat file, which will launch the app and the app will automatically read the double clicked file and load all the settings.
All this needs to happen after the app is compiled and distributed as an executable.
I'm thinking that one way to achieve this is to make a startup window of the app that calls the main window passing the file path as parameter.
Any suggestion would be really appreciated.

Hi, I think I may have a fairly simple, albeit involved, solution for you.
Brief solution overview (TL;DR)
Save the settings from the app with an extension other than .mat, e.g. .mydat. Add an App Input Argument and have the startupFcn treat the argument as a file name to a *.mydat file and be sure to also handle the case that the argument is left out. After the first output file is saved, use windows Open with... to select your app. Now double clicking the *.mydat file will open your app's .exe and will provide the file name of the clicked file to the input argument in your startupFcn.
An example in MATLAB 2018a as a compiled exe on windows 10.
Ok, to start. Let's setup a simple app (I called it runAppFromData) that takes a string input to an edit field and saves it in a file called 'settingsValues.mydat'. It looks like:
The callback for the Save button collects the Value into a local variable called value and then saves it to disk:
% Button pushed function: Save
function save(app, event)
value = app.InputField.Value;%#ok
% User selects save location
saveLocation = uigetdir();
% Now just save the value variable to the selected location.
save(fullfile(saveLocation,'settingsValues.mydat'), 'value', '-mat');
end
I don't know when appdesigner added the feature to "run app with inputs" but I have it with 2018a:
We make a single input, fileName that expects a file name as a string (you'll see why below). So add the input and click OK. Then we're sent to "code view" at the startupFcn. Here we'll write the logic that parses the input file. For my simple example app, I load the input file into a struct and then send the value to the edit field:
% Code that executes after component creation
function startupFcn(app, fileName)
if nargin < 2 % app is itself an argument
% just continue running the application without error
return
end
% fileName is a string, so let's load it into a struc
S = load(fileName, '-mat');
% The value field will be there because that is how we wrote it
app.InputField.Value = S.value;
end
Note, I performed a nargin check to handle the first-run case (and anytime the app is run from the actual executable).
MATLAB doesn't care what the file extension is of a matlab file and if you have an unknown file extension, e.g. .mydata, double-clicking the file in windows will ask you to choose the application, which works to your benefit for deployment:
A couple things to consider.
When the app is opened from the .exe it will always show the default values. If you want to input some other default values you can edit your windows shortcut Target field to supply a file path for the desired input file (see here). This saves recompiling with new defaults, but the file has to remain somewhere (you can package it with the app too).
Sorry this answer got soo long! I hope it helps!

You can't double click a .mat file and open an entire executable, but you can definitely add a startup function that asks you to open a .mat file. My suggestion though would be to make sure that you have a template file at least in place, so that the user doesn't run into problems the first time running the program where there is no file to open.

Related

Does Matlab have "project files"?

For example: Rstudio uses so called projects - text files ending with .Rproj. When you click on a project file, it opens up Rstudio and sets working dir to where the project file is. Optionally, it executes any code written it. However, it does not open itself (i.e., it does not show up in the script editor).
Is there something like that in Matlab? If not, how to emulate it?
Currently I use to make an .m file with cd, addpath calls etc. But when I click in the file browser:
it just opens Matlab and shows up in the script editor without running
opening Matlab is what I want, but showing up in the script editor is actually redundant; I only need to run it (and use the results in my Matlab desktop session)
(What I want to avoid is having to open the script file, run it manually and then having to close it again. It is annoying!)- edited
Matlab does not have "project files" (as far as I know).
However, I think you can easily emulate what you want.
Let's suppose you have your code in a folder C:\MyProject:
1) Create a new m-file C:\MyProject\MyProject.m with all your initialization code (cd, addpath calls, global variables, whatever you need).
Here's a simple example for demonstration purposes:
disp('Replace this with your initialization code');
2) Create a batch-file C:\MyProject\MyProject.bat as follows:
MATLAB -r "run MyProject"
Now, by double-clicking the batch-file you will:
open the complete Matlab environment
execute the script MyProject.m (without loading it in the script editor)
For this purpose, MATLAB offers startup.m files (online documentation).
You have to put all your initialization code in a file called startup.m, which needs to be located within the MATLAB search path (i.e. within your project folder). The script will be executed every time you open MATLAB by double-clicking a arbitrary m-file from your project folder.

waitbar matlab before start a standalone script

I did a standalone application in Matlab and it works. The only problem is that when I launch the application, it takes time before start asking to the user some file (it is the first think the program has to do). The user does not understand if the program is working or not, since no message neither symbol of working progress appear on the screen.
My idea is to show a waitbar until the window asking the file to user appears.
How can I do this? is it possible to use the waitbar outside a loop?
The script starts as follow:
close all
clear all
[filename,pathname] = uigetfile({'*.xlsx'},'Opening File','C:\');
I don't know why, it takes time before open the window for choosing the file.
The time between launch and file selection input appearing is most likely due to the time it takes to load the MCR. You could add a splash screen to your compilation.
If the end user is running from a command line wrap your exe in a system/shell which writes to the command window that the application is starting.
Your issue is most likely the use of clear all. This makes MATLAB remove all variables (in scope, global and persistent), and compiled scripts from memory, forcing it to recompile and load everything again.
If your purpose is to clear all variables in the current scope, you should be able to increase the initial speed of your script by only running clear instead.
Even faster speed can be achieved if you specify which variables to clear using clear var1 var2 ...

How do I write handles from a MATLAB GUI into a .m file?

I am trying to create a GUI for a script that receives paths and matrix names from the user (via uigetdir and uigetfile functions as well as edit text fields), and finally upon pushing the "Run" button writes these handles into a .m file and runs another script.
Essentially, in the end it should create a file called 'RunName'.m that looks something like:
base_path = get(handles.BasePathEdit,'String')
file_name = get(handles.FileNameEdit,'String')
main % runs the main script with the preceding variables defined as they were
and run it.
I'm guessing the script would run successfully if I just write it like that under the 'Run' push-button function, but I would still like for it to create a .m file as described.
Thank you very much for you help,
All the best.
The simplest way of accomplishing this is to write a function that executes upon the pressing of the 'run' button that reads the values from the GUI and the proceeds with the main script. In guide, this is simple - right-click on the 'run' button, and under 'View Callbacks', select 'Callback'. Then you can use the usual syntax get(handles.RELEVANT_TEXT_BOX,'string') etc to read the resr of the data in. You can then pass this to your main function, or you could then just copy and pase your script straight into the callback.

editing objects from MongoDB with an external editor doesn't update the object

I'm using the Mongo shell. I've set my EDITOR to my notepad++ path. I create an object and then I use the EDIT command to edit the obeject using notepad++ but it doesn't update the object.
// mongo shell
var pow = { name: "teest" };
edit pow
// notepad++ opens a document called 'mongo_edit141225123.js' that resides
// in C:\users\...\Appdata\local\temp
// I edit the object, save and close notepad++
pow // object isn't updated :(
what am I missing?
There seem to be a few caveats here. But I can describe how I got this working:
Set the PATH environment variable to include the path to the notepad++ executable. Note to both "apply" this change and not have an existing command line window when doing so. Or at least open a new one once this step is complete.
Specify an EDITOR variable in your command shell window, or otherwise set that under the same system properties as setting the PATH environment variable. Since the program directory is in the PATH just set the executable name:
set EDITOR="notepad++"
Launch your mongo shell and go to edit a variable:
> edit something
This will launch the specified editor, with an "undefined" variable at first. Type in something "valid", as any invalid JavaScript declaration will be discarded. Now for the important part. After your edit and when "closing" click the "tab close" icon and do not close the entire editor as shown:
That last part seems to be the most important. If you are prompted to save (and you likely will be ) then do so. Only "after" the tab has been closed (and saved) should you then close the editor itself.
If you then subsequently issue the same edit something from the mongo shell, then the editor will open with the content that you edited before.
If you don't follow this and just close the editor window first, then you should see an additional tab opened and the original tab with the content that you had before. But subsequent changes will be lost as the shell is now tracking a different temporary file.
So follow those steps and you should be right. I would expect there are similar issues with other external editors that will actually resolve in a similar way.

setting GUI's workspace as the currend workspace

I am writing a GUI program with matlab and I would like to test my variables to see if they are properly imported and to test how to access to different parts of the variables imported so I want my variables to be shown in workspace window of Matlab desktop
the main trouble is if I write a common program in the mfile editor after running the program variables will be shown in workspace windows but about GUI programs its not true
And if I Save the workspace of my program from the path
File>Save Workspace As...
in MFile Editor and then I try to open this access file in desktop i encounter
No variables created
How can I accesss the workspace of my GUI?
If it is just for inspection, the easiest way is to use the debugger: set a breakpoint in one of the GUI callbacks, execution of the code halts there, and allows you to inspect the workspace, among other things.
If you want the GUI to return data to the main workspace, you add the line uiwait(hObject) to the end of the opening function. Then, the callback to e.g. the OK-button should have a line handles.Output=myData; guidata(hObject,handles); to send the variable myData to the GUI output, followed by uiresume(hObject). This way, you can call your GUI as myData = myGUI;, and myData in the base workspace will be filled with whatever data the OK-callback gives it once the OK-button is clicked.
Note: Functions assign outputs, not internal variables to the base workspace. So I guess what you describe as "functions in the editor" are actually scripts that access and modify the contents of the workspace from which they're called.