Getting variables from a custom function with a GUI

I've written a function that creates a GUI requesting the user to input two dates (start and stop). I've included format checking to ensure the user has inputted things correctly.
The part I am missing is how to assign the variables in a way to allows the inputs to be accessible outside the function (i.e. when calling the function with a different script).
Any advice would be appreciated. I can repost sharing the code if that would help.

3 Commenti

Thank you all for the advice. The function is now performing as desired with uiwait. I've included the final version which also includes format verfication using try/catch that ensures the GUI does not close until the dates are provided correctly.
function [startDate, stopDate] = dateInputGUI()
% Set default start and stop dates
defaultStartDate = datestr(datetime('today'), 'dd mmm yyyy HH:MM:SS.FFF');
defaultStopDate = datestr(datetime('tomorrow'), 'dd mmm yyyy HH:MM:SS.FFF');
% Create figure and components
f = figure('Position', [400, 400, 400, 220], 'Name', 'Date Input');
uicontrol('Style','text','String','Expected format: dd mmm yyyy HH:MM:SS.FFF','Position',[50,180,260,20]);
uicontrol('Style', 'text', 'String', 'Start Date:', 'Position', [50, 140, 70, 20]);
startDateEdit = uicontrol('Style', 'edit', 'Position', [130, 140, 220, 20],'String',defaultStartDate);
uicontrol('Style', 'text', 'String', 'Stop Date:', 'Position', [50, 100, 70, 20]);
stopDateEdit = uicontrol('Style', 'edit', 'Position', [130, 100, 220, 20],'String',defaultStopDate);
uicontrol('Style', 'pushbutton', 'String', 'Submit', 'Position', [110, 50, 80, 30], 'Callback', @submitCallback);
% wait until the figure is deleted
uiwait(f);
% Callback function for submit button
function submitCallback(~,~)
startDate = get(startDateEdit, 'String');
stopDate = get(stopDateEdit, 'String');
%Convert to datetime to confirm string is in the correct format and
%that the dates are in order.
try
startDateObj = datetime(startDate, 'InputFormat', 'dd MMM yyyy HH:mm:ss.SSS');
stopDateObj = datetime(stopDate, 'InputFormat', 'dd MMM yyyy HH:mm:ss.SSS');
% Check if start date is before stop date
if startDateObj < stopDateObj
disp('Dates are valid and start date is before stop date.');
delete(f);
else
disp('Error: Start date should be before stop date.');
end
catch
disp('Error: Invalid date format. Please use "dd mmm yyyy HH:MM:SS.FFF".')
end
end
end
Note that DATESTR is deprecated, will be removed in the future, and is NOT recommended.
Replace:
datestr(datetime('today'), 'dd mmm yyyy HH:MM:SS.FFF')
ans = '10 Jan 2024 00:00:00.000'
with e.g.:
string(datetime('today', 'Format','dd MMM yyyy HH:mm:ss.SSS'))
ans = "10 Jan 2024 00:00:00.000"
Thanks for the recommendation @Stephen23. I've made the changes.

Accedi per commentare.

 Risposta accettata

Use uiwait to pause execution of the code, in this case pause until the figure is deleted, and delete the figure in the submit button callback.
function [startDate, stopDate] = dateInputGUI()
% initialize startDate and stopDate in case the user closes the figure
% without clicking the submit button. these variables need to be
% defined in order to be output. (you could also initialize them to
% defaultStartDate and defaultStopDate or something else, depending on
% what you want the outputs to be when the user closes without clicking
% submit.)
startDate = '';
stopDate = '';
% Set default start and stop dates
defaultStartDate = datestr(datetime('today'), 'dd mmm yyyy HH:MM:SS.FFF');
defaultStopDate = datestr(datetime('tomorrow'), 'dd mmm yyyy HH:MM:SS.FFF');
% Create figure and components
f = figure('Position', [400, 400, 400, 220], 'Name', 'Date Input', 'Menubar','none','NumberTitle','off');
uicontrol('Style','text','String','Expected format: dd mmm yyyy HH:MM:SS.FFF','Position',[50,180,300,20]);
uicontrol('Style', 'text', 'String', 'Start Date:', 'Position', [50, 140, 70, 20]);
startDateEdit = uicontrol('Style', 'edit', 'Position', [130, 140, 220, 20],'String',defaultStartDate);
uicontrol('Style', 'text', 'String', 'Stop Date:', 'Position', [50, 100, 70, 20]);
stopDateEdit = uicontrol('Style', 'edit', 'Position', [130, 100, 220, 20],'String',defaultStopDate);
uicontrol('Style', 'pushbutton', 'String', 'Submit', 'Position', [110, 50, 80, 30], 'Callback', @submitCallback);
% wait until the figure is deleted or uiresume(f) is called:
uiwait(f);
% Callback function for submit button
function submitCallback(~, ~)
startDate = get(startDateEdit, 'String');
stopDate = get(stopDateEdit, 'String');
% delete the figure:
delete(f);
end
end

Più risposte (1)

Sonesson
Sonesson il 9 Gen 2024
Modificato: Sonesson il 9 Gen 2024
Hello Charlie,
There are a couple of methods to accsess variables outside of their local function workspace.
The most straightforward is to simply define them as an output variable for the function
%% Script that calls the function handling the user input
[StartDate,StopDate] = FunctionThatGetsUserInputThroughGUI(SomeInput)
%StartDate and StopDate is now available in the workspace that called the
%function.
%Assume you have some function to handle the variables
%Define the output variables as [output1, output2,..., outputN]
function [StartDate, StopDate] = FunctionThatGetsUserInputThroughGUI(SomeInput)
% your code here that creates GUI resulting in the start and stopdate e.g.
StartDate = datetime('yesterday');
StopDate = datetime('today');
end
Less reccommended options would be to use assignin...
%% Script that calls the function handling the user input
FunctionWithAssignin(SomeInput)
%StartDate and StopDate is now available in the workspace that called the
%function.
function FunctionWithAssignin(SomeInput)
% your code here that creates GUI resulting in the start and stopdate e.g.
StartDate = datetime('yesterday');
StopDate = datetime('today');
assignin('caller','StartDate',StartDate)
assignin('caller','StartDate',StartDate)
end
... or global variables
%% Script that calls the function handling the user input
global StartDate StopDate
FunctionWithGlobals(SomeInput)
%StartDate and StopDate is now available in the workspace that called the
%function.
function FunctionWithGlobals(SomeInput)
global StartDate StopDate
% your code here that creates GUI resulting in the start and stopdate e.g.
StartDate = datetime('yesterday');
StopDate = datetime('today');
end
Good Luck!

2 Commenti

Thank you for the response. I am using the first recommended method. I believe my issue is in the GUI functionality itself. My intent is to provide an easy way for the user to input a date and click a submit button. Issue is it seems things move forward without waiting for the user to click "Submit". I'm still new to functions and GUI usage so any advice is appreciated.
function [startDate, stopDate] = dateInputGUI()
% Set default start and stop dates
defaultStartDate = datestr(datetime('today'), 'dd mmm yyyy HH:MM:SS.FFF');
defaultStopDate = datestr(datetime('tomorrow'), 'dd mmm yyyy HH:MM:SS.FFF');
% Create figure and components
f = figure('Position', [400, 400, 400, 220], 'Name', 'Date Input');
uicontrol('Style','text','String','Expected format: dd mmm yyyy HH:MM:SS.FFF','Position',[50,180,260,20]);
uicontrol('Style', 'text', 'String', 'Start Date:', 'Position', [50, 140, 70, 20]);
startDateEdit = uicontrol('Style', 'edit', 'Position', [130, 140, 220, 20],'String',defaultStartDate);
uicontrol('Style', 'text', 'String', 'Stop Date:', 'Position', [50, 100, 70, 20]);
stopDateEdit = uicontrol('Style', 'edit', 'Position', [130, 100, 220, 20],'String',defaultStopDate);
uicontrol('Style', 'pushbutton', 'String', 'Submit', 'Position', [110, 50, 80, 30], 'Callback', @submitCallback);
% Callback function for submit button
function submitCallback(~, ~)
startDate = get(startDateEdit, 'String');
stopDate = get(stopDateEdit, 'String');
end
end
Use WAITFOR or UIWAIT.

Accedi per commentare.

Categorie

Scopri di più su App Building in Centro assistenza e File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by