How to run a matlab file in base workspace from gui - matlab

I'm new in Matlab and I have created a GUI with some push button.
Now, in my current folder I have 4 files:
init.m
example.mdl (simulink)
gui.fig
gui.m
In the gui.fig I have two push buttons:
Init button
start_simulink button
and I would like that when I push on this button the respective action :
start init
start simulink
but I would like that after pressing a button the m file and simulink are performed in a base workspace and not only in a Callback Workspace.
How can I achieve that?

Not exactly what you want, but with the same result. Finally all variables will be in your base workspace, in my eyes it doesn't matter in this case where your scripts initially got called.
For the initialization I assume you're just loading parameters into the base workspace, so you can use a little function in your callback:
function assign2workspace( scriptname )
eval( scriptname );
temp = who;
for iv = 1:length(temp)
assignin('base',temp{iv},eval(temp{iv}));
end
end
where scriptname is you initialization script.
For Simulink you could to do it analogue (untested though)
function startSimulink( modelname )
sim( modelname );
% do what has to be done
temp = who;
for iv = 1:length(temp)
assignin('base',temp{iv},eval(temp{iv}));
end
end

I think my problem was similar to yours. Here's my solution.
Any variable that your script needs from your GUI, be sure to assign it to the base workspace using assignin('base','variablename'). In the callback function for your button, run your script using evalin('base','scriptname')

Related

How exactly should I use open_system to open a Simulink block by using 'handles' instead of a particular Simulink file name in GUI?

I am stuck in my following code because I cannot find out any solution to make a Simulink object, defined in 'open_system', valid in a push button tagged networkselector of my GUI. handles.baseFileName is the chosen file, which I succeeded to open by clicking another push button in an open file window, but I don't know how to use the call operation with 'handles' in 'open_system' correctly to be able to open the Simulink block named NetworkSelector in that file. Also I hope that you help me in this issue.
Thank you very much in advance!
handles.baseFileName
open_system('handles.baseFileName/NetworkSelector')
% push button to open a Simulink file
function open_file_Callback(hObject, eventdata, handles)
startingFolder = 'C:\Users\xxx\Documents'
if ~exist(startingFolder, 'dir')
% If that folder doesn't exist, just start in the current folder.
startingFolder = pwd;
end
% Get the name of the mat file that the user wants to use.
defaultFileName = fullfile(startingFolder, '*.slx')
[handles.baseFileName, folder] = uigetfile(defaultFileName, 'Select a Simulink file')
if handles.baseFileName == 0
% User clicked the Cancel button.
return;
end
fullFileName = fullfile(folder, handles.baseFileName)
[name] = fileparts(fullFileName)
open_system(fullfile('C:\Users\xxx\Documents', handles.baseFileName), 'tab')
guidata( hObject, handles )
% push button to open a Simulink block named NetworkSelector
function networkselector_Callback(hObject, eventdata, handles)
handles.baseFileName
open_system('handles.baseFileName/NetworkSelector')
guidata( hObject, handles )
Error using GUI>networkselector_Callback (line 711)
'handles.baseFileName/NetworkSelector' is not a valid
Simulink object name and no matching file found.
Error in gui_mainfcn (line 95)
feval(varargin{:});
Error in GUI (line 43)
gui_mainfcn(gui_State, varargin{:});
Error in
matlab.graphics.internal.figfile.FigFile/read>#(hObject,eventdata)GUI('networkselector_Callback',hObject,eventdata,guidata(hObject))
- Show complete stack trace
Error while evaluating UIControl Callback.
As per the error message, you don't have a subsystem (literally) called 'handles.baseFileName/NetworkSelector'.
Presumably what you really want is to open the subsystem called [handles.baseFileName,'/NetworkSelector'], that is, using the name of the model stored in handles.baseFileName.
I would suggest that for robustness you also need to wrap the appropriate parts of the code inside a check (using bsIsloaded) to ensure the model is indeed open before trying to open the subsystem.
As you said, I succeeded to remove the extension by writing the following code inside networkselector_Callback:
[pathstr,name,ext] = fileparts(handles.baseFileName);
newFilename = fullfile( pathstr, name );
str = [newFilename,'/NetworkSelector']
open_system(str)
guidata( hObject, handles )
Also it worked. Thank you very much Phil :))

start and pause push button ui matlab

I want to have a ui button that will start and pause a simulation. The script I want to run is a for loop simulation, say the script name is simulation.m.
I set the push button as follows.
start.button = uicontrol('Style','pushbutton','units','normalized',...
'String','Start','Position',[0.1,0.93,0.1,0.05], ...
'Callback',#start_call);
I can't figure out what to write in the callback function (either for running the script or for pausing it
function [] = start_call()
simulation.m;
end
You've basically got it right, you just need to add two things: the callback always takes two input arguments, so even if you don't use them, the function definition needs them. A script is run using the run command. Just change your callback to
function [] = start_call(source, eventdata)
run('simulation.m');
end
Remark: arguments that are not used are commonly replaced by the shorthand ~, which would then read
function start_call(~, ~)
You can also obviously drop the square brackets, if there is no output.

How to disable MATLAB GUI elements DURING (not AFTER) processing a function

It's my first post here, so hello everyone!
My question is about MATLAB GUI interface. In my code, there is a function callback from a pushbutton and I would like to disable every push/slide-able element in my GUI during processing this callback. Unfortunatelly, when I set 'enable' property of these elements to 'off' at the beginning of a callback and then I set it back to 'on' at the end, property doesn't change.
I think I know why it happens. Probably because if callback changes anything, it happens just after the function is finished and every change inside it does not affect any element outside of the function until the processing is done. That's why I don't see all these elements disabled - because at the end of the function I set everything 'on' and that's the only thing which takes place at all.
Regarding to this - is there any option I can change 'enable' property DURING executing a function? Code is shown below:
function [] = mListLaunchButton_call(varargin)
// Some global declarations
global a phi launchBlanker
global servoNumber servoZeroPosition servoDegreePerDegree servoDirection
// Assigning a class
Manual = varargin{3};
// Enabling "Stop" button and disabling everything else
set(Manual.listStopButton,'enable','on');
set(Manual.listSaveButton,'enable','off');
set(Manual.listDeleteButton,'enable','off');
set(Manual.listClearButton,'enable','off');
set(Manual.listLaunchButton,'enable','off');
set(Manual.closeButton,'enable','off');
for i = 1 : 5
set(Manual.sliderDOF(i),'enable','off');
end
%%%%%%%%%%%%%%%%%%%% HERE FUNCTION DOES SOME STUFF %%%%%%%%%%%%%%%%
// Disabling "Stop" button and enabling eveything else
set(Manual.listStopButton,'enable','off');
set(Manual.listSaveButton,'enable','on');
set(Manual.listDeleteButton,'enable','on');
set(Manual.listClearButton,'enable','on');
set(Manual.listLaunchButton,'enable','on');
set(Manual.closeButton,'enable','on');
for i = 1 : 5
set(Manual.sliderDOF(i),'enable','on');
end
Try using the drawnow command after your initial enabling/disabling of GUI controls and before the line:
%%%%%%%%%%%%%%%%%%%% HERE FUNCTION DOES SOME STUFF %%%%%%%%%%%%%%%%
This should cause MATLAB to flush the queued GUI events and update your screen before moving onto the meat of the function.

How would I terminate a program in MatLab from the Command Window without using Ctrl-C? [duplicate]

I would like to be able to terminate my current running scripts( functions ) by calling a command in the code. Return would only terminate the current function not entire script. Therefore return is not the one.
What I am looking for is a command which does exactly what CTRL + C do.
I have already seen this: how to stop execution and noticed that no one has yet provided a proper answer for this question in there either.
ultimately I want to terminate the entire running scripts upon closing a figure:
hFig = figure('CloseRequestFcn',{#closeHandler});
.
.
.
function closeHandler (src,evnt)
CTRL+C <--- I am looking for such a command
end
PS. function error() will not work either: Try this:
function terminateInCode()
hFig = figure('CloseRequestFcn',{#closeHandler});
while(1)
plot(10*rand,10*rand,'+');
pause(0.1);
end;
function closeHandler (src,evnt)
delete(hFig);
error('program terminated!');
end
end
Here is a sample function with example based on yuk's answer. Components include:
Insure the command window has focus to receive the CTRL+C
Use a timer to release CTRL+C after the break has occurred
Use a Java robot to press CTRL+C
Sample function is below:
function terminateExecution
%terminateExecution Emulates CTRL-C
% terminateExecution Stops operation of a program by emulating a
% CTRL-C press by the user.
%
% Running this function
%
%Example:
%for ix = 1:100
% disp(ix)
% if ix>20
% terminateExecution;
% end
%end
%1) request focus be transferred to the command window
% (H/T http://undocumentedmatlab.com/blog/changing-matlab-command-window-colors/)
cmdWindow = com.mathworks.mde.cmdwin.CmdWin.getInstance();
cmdWindow.grabFocus();
%2) Wait for focus transfer to complete (up to 2 seconds)
focustransferTimer = tic;
while ~cmdWindow.isFocusOwner
pause(0.1); %Pause some small interval
if (toc(focustransferTimer) > 2)
error('Error transferring focus for CTRL+C press.')
end
end
%3) Use Java robot to execute a CTRL+C in the (now focused) command window.
%3.1) Setup a timer to relase CTRL + C in 1 second
% Try to reuse an existing timer if possible (this would be a holdover
% from a previous execution)
t_all = timerfindall;
releaseTimer = [];
ix_timer = 1;
while isempty(releaseTimer) && (ix_timer<= length(t_all))
if isequal(t_all(ix_timer).TimerFcn, #releaseCtrl_C)
releaseTimer = t_all(ix_timer);
end
ix_timer = ix_timer+1;
end
if isempty(releaseTimer)
releaseTimer = timer;
releaseTimer.TimerFcn = #releaseCtrl_C;
end
releaseTimer.StartDelay = 1;
start(releaseTimer);
%3.2) Press press CTRL+C
pressCtrl_C
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function pressCtrl_C
import java.awt.Robot;
import java.awt.event.*;
SimKey=Robot;
SimKey.keyPress(KeyEvent.VK_CONTROL);
SimKey.keyPress(KeyEvent.VK_C);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function releaseCtrl_C(ignore1, ignore2)
import java.awt.Robot;
import java.awt.event.*;
SimKey=Robot;
SimKey.keyRelease(KeyEvent.VK_CONTROL);
SimKey.keyRelease(KeyEvent.VK_C);
Not sure it will work, just an idea. How about to emulate keyboard key press from MATLAB?
You can try either java.awd.Robot:
import java.awt.Robot;
import java.awt.event.*;
SimKey=Robot;
SimKey.keyPress(KeyEvent.VK_CONTROL);
SimKey.keyPress(KeyEvent.VK_C);
or WScript.Shell and SendKeys.
Unfortunately, it seems it cannot be done:
Mathworks
There is no way to programmatically issue a Ctrl+C in MATLAB besides using the keyboard's Ctrl+C combination.
As an alternative, you can use the ERROR command to force an error that will exit the code. For example:
error('Program terminated for a specific reason')
Here's an alternative that uses undocumented Matlab calls to place the key event directly into the command window. The method to do so is protected; this uses reflection to unprotect it.
Unlike #yuk and #Persuit's answers, this does not seem to have issues with the control key sticking. Additionally, it will always post directly to the command window without any race conditions or other issues of ensuring focus. And, I think that it fires deterministically -- it'll execute immediately.
The one caveat is that it uses an undocumented call to retreive the handle of the command window instance. This varies slightly by release as it is dependent upon the window frame layout. Some of Yair Altman's (undocumentedmatlab.com) work on the file exchange has more robust functions to grab this in a more general fashion; this code should work with most modern releases of Matlab (Tested on R2011a, both Mac & Win).
function interrupt
import java.awt.event.KeyEvent
import java.util.Calendar
import java.lang.reflection.*
cmdwin = handle(com.mathworks.mde.cmdwin.CmdWin.getInstance().getComponent(0).getComponent(0).getComponent(0),'CallbackProperties');
argSig = javaArray('java.lang.Class',1);
argSig(1) = java.lang.Class.forName('java.awt.event.KeyEvent');
method = cmdwin.getClass().getDeclaredMethod('processKeyEvent',argSig);
method.setAccessible(true);
cal = Calendar.getInstance();
args = javaArray('java.lang.Object',1);
args(1) = KeyEvent(cmdwin,KeyEvent.KEY_PRESSED,cal.getTime().getTime(),KeyEvent.CTRL_DOWN_MASK,KeyEvent.VK_C,KeyEvent.CHAR_UNDEFINED);
method.invoke(cmdwin,args);
You can use the function error. You will go back to matlab.
It will produce an error, but that is also what usually happen when you press CTRL+C, in a matlab script.
You should add some kind of message like error('Interrupted by user');
It is not exactly what you are asking for, but considering your example, your problem can be solved like that:
function terminateInCode()
hFig = figure('CloseRequestFcn',{#closeHandler});
stop=0;
while(~stop)
plot(10*rand,10*rand,'+');
pause(0.1);
end;
function closeHandler (src,evnt)
delete(hFig);
stop=1;
end
end
Try the return statement. It will push you out of a function.
If you want to terminate it completely you need to use ERROR.
You could always use EXIT if its really that disastrous.

Matlab: implementing what CTRL+C does, but in the code

I would like to be able to terminate my current running scripts( functions ) by calling a command in the code. Return would only terminate the current function not entire script. Therefore return is not the one.
What I am looking for is a command which does exactly what CTRL + C do.
I have already seen this: how to stop execution and noticed that no one has yet provided a proper answer for this question in there either.
ultimately I want to terminate the entire running scripts upon closing a figure:
hFig = figure('CloseRequestFcn',{#closeHandler});
.
.
.
function closeHandler (src,evnt)
CTRL+C <--- I am looking for such a command
end
PS. function error() will not work either: Try this:
function terminateInCode()
hFig = figure('CloseRequestFcn',{#closeHandler});
while(1)
plot(10*rand,10*rand,'+');
pause(0.1);
end;
function closeHandler (src,evnt)
delete(hFig);
error('program terminated!');
end
end
Here is a sample function with example based on yuk's answer. Components include:
Insure the command window has focus to receive the CTRL+C
Use a timer to release CTRL+C after the break has occurred
Use a Java robot to press CTRL+C
Sample function is below:
function terminateExecution
%terminateExecution Emulates CTRL-C
% terminateExecution Stops operation of a program by emulating a
% CTRL-C press by the user.
%
% Running this function
%
%Example:
%for ix = 1:100
% disp(ix)
% if ix>20
% terminateExecution;
% end
%end
%1) request focus be transferred to the command window
% (H/T http://undocumentedmatlab.com/blog/changing-matlab-command-window-colors/)
cmdWindow = com.mathworks.mde.cmdwin.CmdWin.getInstance();
cmdWindow.grabFocus();
%2) Wait for focus transfer to complete (up to 2 seconds)
focustransferTimer = tic;
while ~cmdWindow.isFocusOwner
pause(0.1); %Pause some small interval
if (toc(focustransferTimer) > 2)
error('Error transferring focus for CTRL+C press.')
end
end
%3) Use Java robot to execute a CTRL+C in the (now focused) command window.
%3.1) Setup a timer to relase CTRL + C in 1 second
% Try to reuse an existing timer if possible (this would be a holdover
% from a previous execution)
t_all = timerfindall;
releaseTimer = [];
ix_timer = 1;
while isempty(releaseTimer) && (ix_timer<= length(t_all))
if isequal(t_all(ix_timer).TimerFcn, #releaseCtrl_C)
releaseTimer = t_all(ix_timer);
end
ix_timer = ix_timer+1;
end
if isempty(releaseTimer)
releaseTimer = timer;
releaseTimer.TimerFcn = #releaseCtrl_C;
end
releaseTimer.StartDelay = 1;
start(releaseTimer);
%3.2) Press press CTRL+C
pressCtrl_C
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function pressCtrl_C
import java.awt.Robot;
import java.awt.event.*;
SimKey=Robot;
SimKey.keyPress(KeyEvent.VK_CONTROL);
SimKey.keyPress(KeyEvent.VK_C);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function releaseCtrl_C(ignore1, ignore2)
import java.awt.Robot;
import java.awt.event.*;
SimKey=Robot;
SimKey.keyRelease(KeyEvent.VK_CONTROL);
SimKey.keyRelease(KeyEvent.VK_C);
Not sure it will work, just an idea. How about to emulate keyboard key press from MATLAB?
You can try either java.awd.Robot:
import java.awt.Robot;
import java.awt.event.*;
SimKey=Robot;
SimKey.keyPress(KeyEvent.VK_CONTROL);
SimKey.keyPress(KeyEvent.VK_C);
or WScript.Shell and SendKeys.
Unfortunately, it seems it cannot be done:
Mathworks
There is no way to programmatically issue a Ctrl+C in MATLAB besides using the keyboard's Ctrl+C combination.
As an alternative, you can use the ERROR command to force an error that will exit the code. For example:
error('Program terminated for a specific reason')
Here's an alternative that uses undocumented Matlab calls to place the key event directly into the command window. The method to do so is protected; this uses reflection to unprotect it.
Unlike #yuk and #Persuit's answers, this does not seem to have issues with the control key sticking. Additionally, it will always post directly to the command window without any race conditions or other issues of ensuring focus. And, I think that it fires deterministically -- it'll execute immediately.
The one caveat is that it uses an undocumented call to retreive the handle of the command window instance. This varies slightly by release as it is dependent upon the window frame layout. Some of Yair Altman's (undocumentedmatlab.com) work on the file exchange has more robust functions to grab this in a more general fashion; this code should work with most modern releases of Matlab (Tested on R2011a, both Mac & Win).
function interrupt
import java.awt.event.KeyEvent
import java.util.Calendar
import java.lang.reflection.*
cmdwin = handle(com.mathworks.mde.cmdwin.CmdWin.getInstance().getComponent(0).getComponent(0).getComponent(0),'CallbackProperties');
argSig = javaArray('java.lang.Class',1);
argSig(1) = java.lang.Class.forName('java.awt.event.KeyEvent');
method = cmdwin.getClass().getDeclaredMethod('processKeyEvent',argSig);
method.setAccessible(true);
cal = Calendar.getInstance();
args = javaArray('java.lang.Object',1);
args(1) = KeyEvent(cmdwin,KeyEvent.KEY_PRESSED,cal.getTime().getTime(),KeyEvent.CTRL_DOWN_MASK,KeyEvent.VK_C,KeyEvent.CHAR_UNDEFINED);
method.invoke(cmdwin,args);
You can use the function error. You will go back to matlab.
It will produce an error, but that is also what usually happen when you press CTRL+C, in a matlab script.
You should add some kind of message like error('Interrupted by user');
It is not exactly what you are asking for, but considering your example, your problem can be solved like that:
function terminateInCode()
hFig = figure('CloseRequestFcn',{#closeHandler});
stop=0;
while(~stop)
plot(10*rand,10*rand,'+');
pause(0.1);
end;
function closeHandler (src,evnt)
delete(hFig);
stop=1;
end
end
Try the return statement. It will push you out of a function.
If you want to terminate it completely you need to use ERROR.
You could always use EXIT if its really that disastrous.