Appdesigner Print Screen Problem - Appdesigner is a disappointment!

Hi,
I am transitioing to the use of appdesigner, but it seems to suck at printing interface with figures and tables all together.
I saw a post where someone suggested to create a local handle to plot and save a figure, but I am trying to plot everything on the interface including figures, tables, buttons etc.
I tried using print command that I was using in "guide" that was warking perfectly there, but obviously it doesn't work in app designer. Did they purposely make the appdesigner horrible with basic tools like print, save, saveas, rotate, etc... missing so that nobody should use the appdesigner? If I am creating an app, I d want to print it in a way to store it, right?!!! Anyways, this is kind of disappointing. Is there any easy way around this, anybody knows?
I don't want to use an external screen snipping tool b/c the quality of those are not as good and not as professional.
I appreciate any comments!
This is the error I get with "print" command:
Error using print (line 79)
Functionality not supported with figures created with the uifigure function. For more information, see Graphics Support in App Designer.
Error in app2/Button5Pushed (line 82)
print -clipboard -dmeta; % copy the figure to clipboard
Error using matlab.ui.control.internal.controller.ComponentController/executeUserCallback (line 335)
Error while evaluating Button PrivateButtonPushedFcn.

10 Comments

Hi Adam,
Is the screen capture same as what "print -clipboard -dmeta"
or from menu bar => edit -> copy figure ?
I just tried that code from the link you sent and the quality of the image is horrible! And I can't seem to set the boundaries of the app with "pos = app.UIFigure.Position" properly. Which is irrelevant if the quality I am gonna get from the capture is that bad. See what I did below
% get app position
pos = app.UIFigure.Position;
robot = java.awt.Robot();
rect = java.awt.Rectangle(pos(1),pos(2),pos(3),pos(4));
cap = robot.createScreenCapture(rect);
% Convert to an RGB image
rgb = typecast(cap.getRGB(0,0,cap.getWidth,cap.getHeight,[],0,cap.getWidth),'uint8');
imgData = zeros(cap.getHeight,cap.getWidth,3,'uint8');
imgData(:,:,1) = reshape(rgb(3:4:end),cap.getWidth,[])';
imgData(:,:,2) = reshape(rgb(2:4:end),cap.getWidth,[])';
imgData(:,:,3) = reshape(rgb(1:4:end),cap.getWidth,[])';
% Show or save to file
imshow(imgData)
Any other solution for that?
Why isn't matlab enabling those options for the appdesigner?
Bummer. App designer has lots of shiny bells and whistle but there's also a lot of limitations. This question has come up before and I don't think there's currently a solution.
Thanks for your reply, Adam! Yeah appdesigner seems to help do certain things quicker, but it is too limited, pretty much sucks for me b/c I am trying to create an app to get results on screen and quickly plot/print/save... Appdesigner is a disappointment!
I can help you come up with ideas for workaround, if needed. For example, you can copy axes to a regular figure for printing and there are other ways to save the GUI state other than just taking an image of it.
Adam, what are the workarounds? Yeah I got that idea of plotting in sperate figure but I am trying to get everyhing printed out including the tables and buttons so that what options and what input values are inserted would be printed. Saving the GUI state other than taking an image?
Hi,
I too agree. But as Adam suggested you can copy the axes to figure and save it as *.fig, *.jpg etc. I faced intially same problem when I was migrating from GUIDE to Appdesigner.
I manually created zoom-in, zoom-out, select save as Matlab figure or export as Matlab figure etc (as shown below)
appdesigner.PNG
Hi Ankit,
What do you mean by copy the exes? Does that copy everyting including tables and buttons I have on the interface? That's my main problem. "print -clipboard -dmeta" was working for me perfectly on guide.
I would also appreciate if you could explain how you created zoom in/out, saveas, etc.
@Baha411, if the goal is to show the app as a figure embedded in a document, you'll need to rely on 3rd party screenshot programs for now, until matlab creates a way to capture the app image.
If the goal is to save the GUI state so that it can be restored in efforts to replicate the results, you can save the values of each GUI component to a mat file that can then be reloaded upon request. Saving graphics handles can result in very large files so I don't recommend saving the entire "app" structure (but you could try). Instead, you may have to painstakingly save the critical properties (.value. string, etc) of each component. Then, within another function, you can restore those values.
Adam, I am trying to just screen capture whatever is seen in the interface with as good quality as the "print" command was doing. Yeah I am trying to avoid the 3rd party snipping tools for now and not trying to save the entire gui state.

Sign in to comment.

Answers (4)

Adam Danz
Adam Danz on 23 Apr 2020
Edited: Adam Danz on 17 Nov 2020
There are two new functions as of r2020a that address this problem,
They are still a little buggy but I'm sure improvements will come with future releases.
Also take note of copyUIAxes from the file exchange that copies a UIAxes (not an entire figure). I'd first try to use the two functions above, though.
Also see this a Community Highlight to learn about exportapp and getframe with Apps in Matlab r2020b+.
Hi, fortunately the function export_fig() from MATLAB File Exchange now supports exporting uifigures and uiaxes.
Although it still has some limitations like - uicontrols within the uifigures are not being exported, etc.
Hope this helps!

5 Comments

@ Subhadeep Koley , have you tried to apply export_fig() to a UIFigure or UIAxes?
After making a few failed attempts I looked into the most recent code that includes the attempted ui support that was added on 30/10/19 according to internal comments.
It doesn't work with UIAxes (it does work with legacy axes). The reason it doesn't work is because it uses copyobj() to attempt to copy a UIAxes onto a legacy figure but copyobj() isn't supported for UIAxes. As evidence of that,
uax = uiaxes();
fig = figure();
copyobj(uax,fig)
% Error using matlab.ui.control.UIAxes/copyElement
%Functionality not supported with UIAxes. For more information,
% see Graphics Support in App Designer.
The error is not thrown in export_fig() because copyobj() is called from a try/catch that rethrows the error as a modified warning. I'll write to Yair Altman to notify him of these problems (issue 287).
I recently wrote a function copyUIAxes() that copies the children of a UIAxes to a new legacy axes along with the legend and colobar if they exist. But this would not solve the OP's problem since they want to copy the entire App figure.
These methods wouldn't work for copying the entire figure with all buttons and tables in the app designer anyways, right? I agree Adam! Thanks for the contribution though.
@Baha411, you may want to follow the export_fig function (go to the link, click "follow" button). That way you'll get updates on the function. Yair Altman provides some amazing functions to the community and he might come up with workaround to apply this function to UIFigures at some point. It's probably your best bet unless Matlab comes out with a solution in a future release.
Thanks for the advise, Adam! Yeah I have seen some of functions (complicated!). For now I gave up on the appdesigner and I am back to the guide. I hope in future they will make appdesigner more capable. I really appreciate your comments!
If you are using Windows 10, use the "Snipping Tool" (just type that in the search window lower left). Works fine!

Sign in to comment.

Baha411,
I have been trying to find a solution to the same issue. I was able to save my figure to an image file perfectly in GUIDE, which served to screen capture the figure and all of its contents. As Adam states, App Designer does not yet have the functionality to do this in a simple fashion (shame). I have tried to use the new exportgraphics function, but unsuccessfully. However, I have had moderate success by using the following code that uses undocumented features in MATLAB. Its main issue is when using various montitor sizes, configurations, and/or resolutions.
% This option is necessary since saveas() does not work with App Designer's UIFigures.
pause(0.05)
robot = java.awt.Robot();
temp = app.fig_SpeedTrapTool.Position; % returns position as [left bottom width height]
allMonPos = get(0,"MonitorPositions");
curMon = find(temp(1)<(allMonPos(:,1)+allMonPos(:,3)),1,"first");
curMonHeight = allMonPos(curMon,4)+1;
pos = [temp(1),curMonHeight-(temp(2)+temp(4)),temp(3)-1,temp(4)]; % [left top width height]
rect = java.awt.Rectangle(pos(1),pos(2),pos(3),pos(4));
cap = robot.createScreenCapture(rect);
% Convert to an RGB image
rgb = typecast(cap.getRGB(0,0,cap.getWidth,cap.getHeight,[],0,cap.getWidth),"uint8");
imgData = zeros(cap.getHeight,cap.getWidth,3,"uint8");
imgData(:,:,1) = reshape(rgb(3:4:end),cap.getWidth,[])';
imgData(:,:,2) = reshape(rgb(2:4:end),cap.getWidth,[])';
imgData(:,:,3) = reshape(rgb(1:4:end),cap.getWidth,[])';
hImg = imshow(imgData);
saveas(hImg,file,"png")
close(hImg.Parent.Parent)
If you or someone else has been able to come up with a better solution, I would be excited if able to share. Hopefully, Mathworks has plans to improve on the exportgraphics function in a near future upgrade.

4 Comments

Allen,
Thank you very much for this. I may try this at some time in the future, but for now I have given up on AppDesigner and am back to GUIDE. When AppDesigner is truly at (and above) the functionality of GUIDE, I will migrate. The additional knobs and meters may be very useful for Simulink kinds of processes, but doesn't matter to me. Too many issues like this. I hope MathWorks comes out with update announcements with new releases.
Doug
Thanks for your input, Allen. I gave up on the appdesigner, too, but I will keep this on mind for the future. I really appreciate!
If the new functions I mentioned in my answer do not work in r2020a or later, tell the tech support about it: Report a Bug
Hi,
thank you very much for this code!
I had some trouble with a multi monitor setup, which I could resolve by replacing this line:
pos = [temp(1) curMonHeight-(temp(2)-allMonPos(curMon,2)+1+temp(4)) temp(3)-1 temp(4)];
Cheers,
Florian

Sign in to comment.

So after a bit more digging around I found exportapp(fig,filename), which does exactly as needed.

3 Comments

Yes, that's the function I was pointing to in the Community Highlight link in my answer but that wasn't so clear (I clarified it). Also see getframe which is also demonstrated in that link. Both of these will require Matlab r2020b or later if you're using it with AppDesigner.
Adam, I have to admit that I missed your Community Highlight link. I use getframe often for animating 2D position plots as a function of time. Works great there, but never saw it as I screen capture tool for App Designer. Thanks for the tip.
It just became available for Apps in r2020b. Glad I could help.

Sign in to comment.

Categories

Find more on Environment and Settings in Help Center and File Exchange

Products

Release

R2019a

Asked:

on 1 Oct 2019

Edited:

on 8 Jun 2021

Community Treasure Hunt

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

Start Hunting!