Determine if Matlab has a display available

2020-02-08 13:16发布

I would like to use questdlg within a Matlab application to prompt user feedback. If no display is available (e.g. over a non-forwarded ssh session or if Matlab is started with -nodisplay), questdlg fails (see below). Is there any way to determine if a display is available from within Matlab code so that I can fall back to a text-based alternative?

If Matlab is started with the -nodisplay option, qusetdlg produces the following output and "hangs" Matlab (in uiwait). Although the user can use Ctl-C to escape, there's no indication of this option and a naive user might conclude that Matlab was truly hung:

>> questdlg('test','test')
Warning: This functionality is no longer supported under the -nodisplay and
-noFigureWindows startup options. For more information, see "Changes to
-nodisplay and -noFigureWindows Startup Options" in the MATLAB Release Notes.
To view the release note in your system browser, run
web('http://www.mathworks.com/access/helpdesk/help/techdoc/rn/br5ktrh-1.html#br5ktrh-3',
'-browser') 
> In uitools/private/warnfiguredialog at 19
  In dialog at 37
  In questdlg at 117
Warning: This functionality is no longer supported under the -nodisplay and
-noFigureWindows startup options. For more information, see "Changes to
-nodisplay and -noFigureWindows Startup Options" in the MATLAB Release Notes.
To view the release note in your system browser, run
web('http://www.mathworks.com/access/helpdesk/help/techdoc/rn/br5ktrh-1.html#br5ktrh-3',
'-browser') 
> In uitools/private/warnfiguredialog at 19
  In uiwait at 41
  In questdlg at 378

5条回答
Bombasti
2楼-- · 2020-02-08 13:55

Not sure if this will work, but you could try the usejava function with the 'desktop' parameter.

查看更多
一纸荒年 Trace。
3楼-- · 2020-02-08 14:08

@Amro's answer on this page is fine but does not work within parfor loops. In fact, none of the usejava() and feature('ShowFigureWindows') based solutions work in that case because the environment changes once a parfor loop starts.

A reliable way is @gnovice's answer. Specifically:

parfor k=1:N
    scr = get(0,'ScreenSize');
    if isequal(scr(3:4),[1 1])
        % text-based version
    else
        % GUI version
    end
end

Alternatively, you could apply either solution before entering the parfor loop, store the result in a variable, and then check only that variable within the parfor loop:

scr = get(0,'ScreenSize');
istext = isequal(scr(3:4),[1 1]);

% or

istext = ~usejava('jvm') || ~feature('ShowFigureWindows');

parfor k=1:N
   if istext
       % text-based version
   else
       % GUI version
   end
end

However, depending on your application, this may not be reliable (e.g. if the parfor loop changes context, but that's uncommon).

查看更多
淡お忘
4楼-- · 2020-02-08 14:16

First of all, here is a list of relevant startup options, along with the operating system on which they are supported (otherwise they are ignored and have no effect):

  • -nojvm [UNIX] : start without JVM, anything that requires Java fails (including Handle Graphics functionality)
  • -nodisplay [UNIX]: does not use X-Window display, ignores $DISPLAY environment variable
  • -noFigureWindows [ALL] : headless mode, no figure will be shown
  • -nodesktop [ALL] : IDE not started, command prompt instead

Since I only have access to a Windows install of MATLAB, I would be thankful If someone can replicate the following experiments on UNIX, by starting MATLAB with the -nodisplay option, or runing without the DISPLAY environment variable set, in combination with the -nodisplay and -nojvm options.

matlab -nodesktop

» [usejava('jvm'),usejava('awt'),usejava('mwt'),usejava('Desktop')]
ans =
     1     1     1     0
» get(0,'ScreenSize')
ans =
           1           1        1600        1024
» feature('ShowFigureWindows')
ans =
     1
» questdlg('?','?');
[works fine]
» plot(1:10)
[works fine]

matlab -noFigureWindows

» [usejava('jvm'),usejava('awt'),usejava('mwt'),usejava('Desktop')]
ans =
     1     1     1     1
» get(0,'ScreenSize')
ans =
           1           1        1600        1024
» feature('ShowFigureWindows')
ans =
     0
» questdlg('?','?');
Warning: This functionality is no longer supported ....
» plot(1:10)
[no plot]

matlab -nodesktop -noFigureWindows

» [usejava('jvm'),usejava('awt'),usejava('mwt'),usejava('Desktop')]
ans =
     1     1     1     0
» get(0,'ScreenSize')
ans =
           1           1        1600        1024
» feature('ShowFigureWindows')
ans =
     0
» questdlg('?','?');
Warning: This functionality is no longer supported ....
» plot(1:10)
[no plot]

In conclusion, this is the test I would use to get consistent results across platforms:

if usejava('jvm') && ~feature('ShowFigureWindows')
    %# use text-based alternative (input)
else
    %# use GUI dialogs (questdlg)
end

Some references:

查看更多
欢心
5楼-- · 2020-02-08 14:20

This MATLAB newsgroup thread suggests that checking the third and fourth values of the root object 'ScreenSize' property will tell you if a display is available. I can't test it at the moment, but you could try adding this to your code:

screenSize = get(0,'ScreenSize');
if isequal(screenSize(3:4),[1 1])
  %# Use text-based alternative
else
  %# Call questdlg
end
查看更多
放荡不羁爱自由
6楼-- · 2020-02-08 14:21

is_gui_mode = usejava('desktop') && usejava('awt');

查看更多
登录 后发表回答