How do I set up a uigetdir with a Push button in appdesigner ?

Hi All
I need to have a push button that when I press, the uigetdir command activates and allows the user to choose the desired directory , and pass this to the main code that will be run via the app. I have been unsuccessful and I get errors

1 Comment

Could someone help ? I am searching everywhere , and no hope so far ! It's frustrating, cause appdesigner and GUI can't be tested in command prompt and I don't know why the edit field works but button with uigetdir not

Sign in to comment.

 Accepted Answer

Step 1: Add callback function to the Button
Right click the button from within appdesigner and add a callback function.
Step 2: add 'selectedPath' as a private property
This variable will store the user's selected path. You can name the variable anything you want.
From the Code View in appdesigner, go to the CODE BROWSER, select Properties, and press the green "+" button.
This will add a new private property. Rename it to selectedPath or whatever other name you want and set a default value. The default value will be used if this variable is accessed prior to the user choosing a path. The default value can be empty (selectedPath = '';). Add a commented description of the variable.
Step 3: Call uigetdir from the button's callback function
Call the uigetdir function from within the button's callback function. Choose which inputs you need. Store the output in app.selectPath using the same variable name as you declared as a private property.
function ButtonPushed(app, event)
app.selectedPath = uigetdir(); % <-- add this line
end
Step 4: Access the chosen path
From anywhere in your app, you can access the selected (or default) path by using
app.selectedPath

12 Comments

Thank you So much! Will this work, for the case I compile the app together with the mfiles that it will run ? that originally are in that folder when not compiled but will be inside the exe in installation folder when compiled ?
In that case, I would set the default path to an empty array. Any time that variable is accessed in your app you can test that it's not empty.
selectedPath = ''; % example of default value
Test it
if isempty(selectedPath)
error('This user must first selecte a path by pressing the Select Path button.')
% or whatever the button is called ^^^^^^^^^^^
end
Note that the use of uigetdir can cause problems in compiled apps. I'm not sure whether this bug has been fixed. For more info:
Thank you very much !
So just to let you know what I need exactly :
I have main file and some functions in the main folder, then I have a subfolder for input excel files and one for output excel files.
so : in the app, I should direct to the main folder, where the code can go read the inputs and have access to the output folder. but once I compile it, the mfiles are not anymore in the main folder but in the exe file , in the installation directory that is normally the C dirve. but I don't want to ask the user to copy the files to the installation directory.
but an idea came to my mind , that if the compiled application is always installed in the same directory, so I can copy the input files to the installation directory and run them there and then copy the outputs back to the user directory. Is it feasible ?
then : I have created two buttons, one for uigetdir as you helped and the other one to run the mfile.
the run mfile does not work and gives error :
% Button pushed function: ChooseDirectoryButton
function ChooseDirectoryButtonPushed(app, event)
global currentFolder
app.selectedPath = uigetdir();
currentFolder=app.selectedPath;
cd(currentFolder)
end
% Button pushed function: ExecuteButton
function ExecuteButtonPushed(app, event)
global currentFolder;
cd(currentFolder)
assignin('base','currentFolder',currentFolder);
goFolder = strcat(currentFolder,'\mysolver.m');
run(goFolder)
in mysolver mfile I have the first lines :
global currentFolder
inputfolder =strcat(currentFolder,'\Inputs');
cd(inputfolder)
the error : it seems that the cd is performed too fast , even before the lines above it
Error using cd
Cannot CD to \Inputs (Name is nonexistent or not a directory).
Error in mysolver (line 36)
cd(inputfolder)
Error in run (line 91)
evalin('caller', strcat(script, ';'));
Error in apprivate/ExecuteButtonPushed (line 33)
run(goFolder)
Error using matlab.ui.control.internal.controller.ComponentController/executeUserCallback (line 309)
Error while evaluating Button PrivateButtonPushedFcn.
Is it feasible ?
It seems feasible enough to give it a try. I don't have experience using a compiled app so my feedback is limited.
Don't use global variables. Instead, declair the variables as a property as I have shown in step 2 of my answer. In fact, app.selectedPath is already a variable accessible anywhere within the app.
dear Adam, I still have problem about my above comment. Yes, app.selectedPath is available within the app, but I only want to use the app window as a current folder indicator and post processing, but as you can see in the Execution button, I run the whole calculation in another mfile , in which I should cd() between the main and sub folders.
this works if I directly run the main mfile, but now after defining the
currentFolder = app.selectedPath
I should be able to use it "OUTSIDE THE APP". that is the problem
In that case, selectPath should be declared as a public property instead of private. Then it will be accessible outside of the app.
After doing that, when you open the main app, store it's handle.
app = mainApp; %or whatever your app is called
then you can access the public property values from outside the app.
app.selectPath
dear Adam, the links do not work.
Anyway : the fact is : when now I press the ChooseDirectory, the code successfully changes the current directory of MATLAB to the desired one. but when I run the mfile from the app, the cd() line that I wrote in the comment above ,does not work.
with this error despite that the subfolder name is defined in the line before cd(inputs), MATLAB does not create the subfolder variable and can not do the cd(inputs)
Ok , now I see the problem , exactly the
currentFolder = app.selectPath
has not been shared with the m file and that is why it's not even able to create and find the subfolder.
I did not understand where in the app should I write
app= mainApp ;
and how should I call it
This is covered in the 2nd link in my previous comment. I just tested the links and they work for me.
Dear Adam, with one problem : I could check the link, it talks about two GUI windows and exchanging variables between them. It will be useful for me further ahead.
at the moment, I need to share the variable : currentFolder which is a char variable ( folder address) with
Matlab workspace. So : by using global variable or the public ( I see both of them can do) I see the currentFolder variable in Matlab Variables Window ! BUT : when I type currentFolder in command prompt It's EMPTY !!! that's weird and I don't know how to resolve this !
ok , it seems that it's the
assignin('base','currentFolder',currentFolder);
line that send the variable to matlab workspace, but still ,when the Mfile runs, it can not read it. I think it's a matter of time and velocity of execution.
should I use uiwait ? is it relevant ?
Have you switched from using global variables to using public properties? Global variables cause all sorts of problems.
Lots of problems can arise by using assignin(), too. I hadn't noticed that line in your code until you mentioned it. Again, declaring currentFolder as a public property is a better option. If you want to access the currentFolder variable from the base workspace, you could do so like this:
app = myApp; % myApp is the name of your app; this is how you open the app.
app.currentFolder

Sign in to comment.

More Answers (0)

Categories

Find more on Develop Apps Using App Designer in Help Center and File Exchange

Asked:

on 18 Mar 2020

Commented:

on 19 Mar 2020

Community Treasure Hunt

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

Start Hunting!