access matlab figures by opening them with a mouse while a matlab terminal application is still running

So i have a deployable terminal application that is a utility sent to colleagues of mine.
It a menu based navigation system that allows the user to do certain thigns. One of those thigns is generate some basic plots.
The menu system continues to be called inside of an infinte while loop until the user selects exit.
The problem i have is the following.
Because the program is running, after the user uses one of the menu options to make some plots that now exist in the working directory, the user can not open the plots because the program is still activley running like it should be unless the user selects exit. Its sitting there waiting for the next thing the user wants to do.
I need to find a way to let the user look at plots in the working direcotry (open them) while the program is still running.
"pause" should of been able to do this but it cant. The plots will still not open while pause is being called.
using the "keyboard" function does actually work. if i put a "keyboard" in, the program waits. The user can open plots and such.
However, the only way to return from the keyboard function is to manually type DBCONT in the terminal. This is not acceptable for a user app.
What i would like to do, is have a message that pops up and says "press any key to continue" in the background the keyboard function is called so they can open plots.
The question is. how do i programattically call DBCONT when a user pushes any key after having called the keyboard function?
I have not found a way yet or an alternative. Sorry, i am restricted from posting the code. An example can made by jsut typing the pause command in a matlab terminal and trying to open a figure. It wont let you. Then try it with keyboard and you will see you can open a figure.
but how to get back into the main loop is the question.
Thanks

Answers (4)

Here is one way of calling dbcont to exit debug mode without user typing it this FEX
keyboard
... wait until user do his/her stuff
inputemu('key_normal','dbcont\enter'); % File exchange
What does "make some plots" exactly mean? .fig-files? PNG-files with raster copies of diagrams? What is the reason that they cannot be "opened" and with which software do you want to open them? Why does the running program prevent the "plots" to be opened?
Using keyboard to stop the execution might be working, but is sounds like a poor design. Remember that the user have an open debug console and inputs can have strange side-effects.
"how do i programattically call DBCONT when a user pushes any key after having called the keyboard function?" - My answer is the same as in the other discussion we had today: The best solution is to avoid the need to do so. In your case an explicit solution might be to let the created figures stay open (if this is meant by "make some plots"). Why are the "plots" closed before?
Another option is to avoid terminal applications with text menus, which run in a loop until the user selects "exit". This sounds like MS-DOS interfaces from 1985. Wouldn't a standard GUI be much more user-friendly?
By the way: You could use FEX: textinject and java.awt.robot to magically type "dbcont" in the command window. This is the ultimative hacking style and far beyond clean code. I'd avoid such indirections, because they let the complexity of the code explode and reduce the independency from the platform.
Summary: Refactor your code to use a standard GUI instead of fiddling in the debug console.

7 Comments

What does "make some plots" exactly mean? .fig-files? PNG-files with raster copies of diagrams? What is the reason that they cannot be "opened" and with which software do you want to open them? Why does the running program prevent the "plots" to be opened?
"make some plots" meaning calling the matlab plot function to create a figure, plot data, and save the .fig into the current working directory.
Why cant it be opened???? Beats me, ask mathworks. I’m trying to open them inside of matlab.
The program uses the "input" function and sits and waits for the user to make there next menu selection. The user may want to open a matlab figure that was created by the previous task completed by the program. While the program is sitting and waiting for the input from the user on what to do next, no plots can be opened.
This can be tested by simply typing in the terminal " input('get some input')" and while doing this go try and open a matlab figure.
I am not saying keyboard is a good option. I’m saying its the only one i have found that works even half way but since its only half way, now I’m discussing programmatically calling DBCONT. I would rather not and I’m well aware this is a poor approach. There are no other options since matlab pause function will also STILL not allow users to use or click on anything in the matlab UI despite what the documentation says.
Test the same theory as above, but instead of using input, use keyboard and then try and open a plot. You CAN open a plot inside of matlab after having called keyboard.
This is a console application with a standard menu system that comes up.
Why not use a gui? Because the matlab gui tool is first of all a nightmare. Second of all, i don’t have time for the additional development time to build a GUI for something that can be a console up in 1/10th the time and cost.
I’m not fiddingling in a debug console, this is a console app the runs at a terminal. It is also a deployable app that gets packaged.
@Robert Scott: "I’m trying to open them inside of matlab." - I cannot read your mind, so please explain this in detail. How do you try to open the fig-file? You have mentioned, that the program is a "deployable terminal application". So do you try to open the fig file in the same Matlab session? With a double click on the file?
Why are the figures closed at all? Is leaving them open an option? Even than callbacks of the figure are not evaluated during a pause() blocks Matlab.
"This can be tested by simply typing in the terminal " input('get some input')" and while doing this go try and open a matlab figure." - As mentioned already, I would avoid this strictly. I'd create a GUI with an edit field, which replaces the input() in the command window. While the GUI is waiting for the callback of the edit field to be triggered, it is trivial to open fig files in the same Matlab session.
Creating GUIs programmatically is easy and not a nightmare. With the modern AppDesigner it became even simpler. GUIs have the advantage that the usability is much higher and that you can avoid dirty tricks to control the program flow. Console apps are useful if only the console is is used. For the interactive creation and analysis of figures it is not a good option.
So the only hard argument is, that you ran out of time for the project. You see, that the decision for a console app have caused unexpected troubles, which can be fixed with dirty tricks only. Project management is another topic for succesful production of software.
So did you try textinject or the awt.robot to magically inject a "dbcont" in the command window? It is a bad suggestion, because you ran into a bad problem. I strongly recomment other readers to prefer a different design instead. But it is solves your needs in the remaining time - who cares?!
"Why cant it be opened???? Beats me, ask mathworks." - I spend some time to suggest solutions and ideas. You are rather impolite in another dicussion, but I'm interested in the Matlab problem only. A businesslike wording would support this. Thanks.
@Robert Scott If by "deployable" app you meant compiler app (using MCC) then you must thing again, keyboard and dbcont are not intended for deployable app se https://www.mathworks.com/help/compiler_sdk/ml_code/unsupported-functions.html
keyboard is intended for debugging purpose, the doc oage mentions this
"keyboard pauses execution of a running program and gives control to the keyboard. Place the keyboard function in a program at the location where you want MATLAB® to pause. When the program pauses, the prompt in the Command Window changes to K>>, indicating that MATLAB is in debug mode. You then can view or change the values of variables to see if the new values produce expected results.
The keyboard function is useful for debugging your functions."
he typical use case in it enters to debugging mode. Debugging mode is not suitable for regular app, and NOT for console command mode,
Thanks, i was aware of that but thanks for the feedback. I should of been more clear in this regard. The compiler app version of this is a side project and unrelated.
However, the console app itself is a matlab app that runs inside of matlab. So for a breif moment, the keyboard hack was a viable albeit miserable solution.
In case i have not been clear, the keyboard option is a poor choice which i have pointed out in a few spots. I have not found a suitable solution but would like to avoid keyboard of course.
There are millions of console applications in the world that do not require a gui. The reason the plots must be closed after generation is because there are hundreds and hundreds of them created. Therefore leaving them open is not a solution.
Then I recommend yoi to prompt user (use INPUT command) then parse the string and do the action, might be with EVAL.
Alternatively if you stop the program with KEYBOARD then what is the problem to tell user to type DBCONT to resume? After all the end user is under MATLAB debug mode.
But again why not create a gui that invites the end user to do whayever he/she supposes to do, even with Tinput string? Then you can resume the program with command such as WAITFOR? Beside INPUT, There are other control functions that suppose to control the workflow through CALLBACK, etc... You should not use KEYBOARD to controll the workflow other than for debuggng purpose.
We can close this, it appears there is no solution.
@Robert Scott: "There are millions of console applications in the world that do not require a gui." - This is correct. These applications are "single-threaded". This means, that the main task controls the program flow and does not leave a way for the user, to use the Matlab session to anything else, e.g. to open figures. This means, that a console application cannot solve your needs.
Modern software, e.g. operating systems, are multi-threaded: You can leave the current application and use another one to process other data. This can be done in a Matlab session by a GUI, which blocks the execution only while its callbacks are processed (see the 'Interruptible' property), but afterwards you have full access to Matlab's engine, while the GUI is waiting in the background for the next user interaction.
I've tried it for some days to use the command window for user interactions also, struggeled with keyboard and dbcont or tricky java hacks, which infiltrates the command window's input and output. Now I'm convinced, that there is no clean and stable way to do this. Even the suggested textinject and java.awt.robot are ugly hacks only (by the way, did you trie them?).
An experienced programmer needs less than an hour to create a GUI with some menu elements programmatically. The AppDesigner or even the outdated GUIDE can be useful also.

Sign in to comment.

Because the program is running, after the user uses one of the menu options to make some plots that now exist in the working directory, the user can not open the plots because the program is still activley running like it should be unless the user selects exit. Its sitting there waiting for the next thing the user wants to do.
If having this application be menu-based is a hard requirement that cannot be changed, I think one option is to have a menu option that allows the user to select a file to open (either by typing the name of a figure file in the current directory or by using something like uigetfile) then have the program open the file.

6 Comments

Thanks for the suggestion Steve.
That is a solution. Its not viable for me since there are hundreds of plots that the app creates. The users typically open one look at it for a second, then close it, then open another, and maybe do this 30 or 40 times until they see what they want to see. The the user may select a different data set and tell it generate a few hundred more plots and around and around we go. Forcing them to type in the file names would create a very tedious workflow. but it is indeed a viable option. I appreciate the suggestion.
If you have Image Processing Toolbox, I wonder if displaying a montage of your images would be sufficient.
It is not clear for us how able to programmatically exit debug mode can save user for tedious work.
Actually its is not clear how your command line would work (specification of the workfows after the code hits keyboard command). What user supposes to do from there? How he/she would do in order to plot a figure? How he/she selects the figure? Cancel or Validate it is the right one? They are facing a DEBUG mode commands with a prompt
K >>
, if they type Ctrl C, or CLEAR, or QUIT or EXIT are those actions bother you?
If instead of doing this
openuserprompt()
keyboard
dootherstuffs
try to do this
figh = openuserpromptinFigure()
waitfor(figh)
dootherstuffs
figh can be a handle of an invisible figure that you create in a non blocking way and is returns from openuserpromptinFigure. When user finishes his/her selection tasks you just need to delete secretly figh so that your program goes to dootherstuffs
Just as a side note, the keyboard command was actually the solution provided by mathworks in my support ticket.
Another option is to open a 2nd Matlab session to examing the figures:
!matlab -r "openfig('your.fig')"

Sign in to comment.

This took 4 minutes for writing:
function MainGUI
FigH = figure('Name', 'Main GUI', ...
'MenuBar', 'none', ...
'NumberTitle', 'off', ...
'Resize', 'off', ...
'BusyAction', 'cancel', ... % Block new actions during computing
'DeleteFcn', @Exit_CB, ...
'CloseRequestFcn', @Exit_CB);
StartButtonH = uicontrol(FigH, 'Style', 'PushButton', ...
'String', 'Next request', ...
'FontSize', 20, ...
'Units', 'Normalized', ...
'Position', [0.1, 0.55, 0.8, 0.35], ...
'Callback', @Start_CB);
ExitButtonH = uicontrol(FigH, 'Style', 'PushButton', ...
'String', 'Exit', ...
'FontSize', 20, ...
'Units', 'Normalized', ...
'Position', [0.1, 0.1, 0.8, 0.35], ...
'Callback', @Exit_CB);
end
function Start_CB(StartButtonH, EventData)
% Disable the button temporarily:
origString = get(StartButtonH, 'String');
set(StartButtonH, 'String', 'Please wait...', 'Enable', 'off');
drawnow;
% Call your script or function containing the menu here
yourTool;
% Restore the button:
set(StartButtonH, 'String', origString, 'Enable', 'on');
end
function Exit_CB(FigH, EventData)
set(FigH, 'DeleteFcn', '');
delete(FigH);
end
Remove the loop from your code and let the GUI trigger the next call instead. When the script "yourTool" is finished, the Matlab session is free for any access, while the GUI is waiting in the background.
In a next step you can include the menu of your script and the input() command in the figure until the command window is not needed anymore. A dropdown menu or edit field might be useful and is implemented by the same uicontrol() commands.
With such a GUI you can omit the keyboard command and have no need to inject a dbcont.

Categories

Find more on App Building in Help Center and File Exchange

Products

Release

R2021b

Asked:

on 27 Feb 2023

Edited:

Jan
on 1 Mar 2023

Community Treasure Hunt

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

Start Hunting!