You are now following this question
- You will see updates in your followed content feed.
- You may receive emails, depending on your communication preferences.
UICONTEXTMENU will not appear on GUI
3 views (last 30 days)
Show older comments
Lawson Hoover
on 9 Dec 2012
I have been trying to get a context menu to appear anywhere on the eniter figure, which also has a plot on it. I have this code:
cmenu = uicontextmenu('Parent',S.fh);
bgmenu = uimenu(cmenu,'label','Background');
bg1 = uimenu(bgmenu,'Label','Grid','CallBack',set(imread,'filename','grid.jpg'));
bg2 = uimenu(bgmenu,'Label','ConTrail','Callback',set(imread,'filename','grid.png'));
bg3 = uimenu(bgmenu,'Label','Opera','Callback',set(imread,'filename','Opera.jpg'));
The Menu will not show up at all.
Accepted Answer
Matt Fig
on 9 Dec 2012
Edited: Matt Fig
on 9 Dec 2012
You need to set the uicontextmenu property, not assign a parent.
S.fh = figure;
cmenu = uicontextmenu;
bgmenu = uimenu(cmenu,'label','Background');
set(gcf,'uicontextmenu',cmenu)
Now right click inside the figure....
17 Comments
Lawson Hoover
on 9 Dec 2012
It still wont work, maybe the way I set the back ground has to do with it. I set the background image with:
ImAxes = axes('Parent',S.fh,'units','normalized','Position',[0 0 1 1]);
I = imread('light wood.jpg');
Im = imagesc(I);
colormap gray
set(ImAxes,...
'handlevisibility','off', ...
'visible','off');
Walter Roberson
on 9 Dec 2012
set HitTest off on the axes and the Im
Lawson Hoover
on 9 Dec 2012
You are the man! Thank you! Also how would I change what image is load when a selection is made?
Walter Roberson
on 9 Dec 2012
set() the CData property of Im to change the image.
Lawson Hoover
on 9 Dec 2012
I did that but now When I set the call back to this:
bg1 = uimenu(bgmenu,'Label','Grid','Callback',set(Im,'CData','grid.jpg'));
The first level of the context menu shows up but then nothing else shows up. I think I am setting up the callback wrong.
Matt Fig
on 9 Dec 2012
Edited: Matt Fig
on 9 Dec 2012
To clear up the previous point.... Setting the hittest to off makes it so that when you click on the axes or image the object that is selected is whatever is below those two (i.e., they cannot become the selected object), which is the figure. Otherwise you would need to set the uicontextmenu of those objects rather than the figure like you showed in your OP.
Lawson Hoover
on 9 Dec 2012
Ok, so when I turn the HitTest off, I wont allow me to change the file name on the back ground image? I understand that when it is off It is essentially clicking the back most figure. But why cant I change the file name for the background image?
Matt Fig
on 9 Dec 2012
Show the code. Nobody can know what you are doing or why MATLAB isn't giving you what you expect if we don't see the code. Are you still setting the callback to this:
set(imread,'filename','grid.jpg')
I can't believe that won't error, unless you have masked the IMREAD function with a variable!
Lawson Hoover
on 9 Dec 2012
Setting up background image:
ImAxes = axes('Parent',S.fh,'units','normalized','Position',[0 0 1 1],'HitTest','off');
%uistack(ImAxes,'bottom');
I = imread('ConTrail.png');
Im = imagesc(I,'HitTest','off');
colormap gray
set(ImAxes,...
'handlevisibility','off', ...
'visible','off');
and then the associating context menu code.
cmenu = uicontextmenu;
bgmenu = uimenu(cmenu,'label','Background');
set(gcf,'uicontextmenu',cmenu)
bg1 = uimenu(bgmenu,'Label','Grid','Callback',set(Im,'CData','grid.jpg'));
bg2 = uimenu(bgmenu,'Label','ConTrail');
bg3 = uimenu(bgmenu,'Label','Opera');
bg4 = uimenu(bgmenu,'Label','Light Wood');
If you need more I can just load the first whole section of the code. That creates the GUI
Matt Fig
on 9 Dec 2012
Edited: Matt Fig
on 9 Dec 2012
I don't think you are programming callbacks correctly. Are you telling me that code doesn't produce an error when you run it? Your callback is a function that will run when the callback is invoked.
Here is a short and simple example of how to load different images and set them depending on the results of a context menu. Notice how the callback is set and used.
function [] = gui_image_change()
S.fh = figure('units','pixels',...
'position',[400 400 480 300],...
'menubar','none',...
'name','Image_GUI',...
'resize','off',...
'numbertitle','off');
S.ax = axes('units','pixels',...
'position',[0 0 480 300],...
'xtick',[],'ytick',[]);
X = load('clown'); % This is a built-in ML example.
IMG = ind2rgb(X.X,X.map); % We want to convert it to RGB.
imwrite(IMG,'myclown_IMG.jpg','jpg'); % Save to disk.
S.IH = image(IMG); % Display the image.
% Save variants to disk. In practice these
% would already be on disk so you could
% skip this step and just use the names in
% the callback.
I = IMG; I(:,:,1) = .8;
imwrite(I,'myclown_red_IMG.jpg','jpg');
I = IMG; I(:,:,2) = .8;
imwrite(I,'myclown_green_IMG.jpg','jpg');
I = IMG; I(:,:,3) = .8;
imwrite(I,'myclown_blue_IMG.jpg','jpg');
S.UCM = uicontextmenu;
S.UM(1) = uimenu(S.UCM,'Label','Plain');
S.UM(2) = uimenu(S.UCM,'Label','Red');
S.UM(3) = uimenu(S.UCM,'Label','Green');
S.UM(4) = uimenu(S.UCM,'Label','Blue');
set(S.IH,'uicontextm',S.UCM)
set(S.UM,'CallBack',@menu_call);
guidata(S.fh,S) % Save the structure for later use.
function [] = menu_call(varargin)
% Callbacks for the menus
S = guidata(gcbf); % Get the structure
switch gcbo
case S.UM(1)
I = imread('myclown_IMG.jpg');
case S.UM(2)
I = imread('myclown_red_IMG.jpg');
case S.UM(3)
I = imread('myclown_green_IMG.jpg');
case S.UM(4)
I = imread('myclown_blue_IMG.jpg');
otherwise
disp('Twilight Zone!')
end
set(S.IH,'cdata',I)
Lawson Hoover
on 9 Dec 2012
Ok so I read it over and created a dedicated call back but now It is saying:
Attempt to reference field of non-structure array.
Error in Beam_Deflection_GUI_3>menu_call (line 342)
case S.um(1)
Error while evaluating uimenu Callback
I used the same set up code to create the background image and made the uimenu this:
cmenu = uicontextmenu; bgmenu = uimenu(cmenu,'label','Background'); set(gcf,'uicontextmenu',cmenu)
S.um(1) = uimenu(bgmenu,'Label','Grid');
S.um(2) = uimenu(bgmenu,'Label','ConTrail');
S.um(3) = uimenu(bgmenu,'Label','Opera');
S.um(4) = uimenu(bgmenu,'Label','Light Wood');
set(S.um,'CallBack',@menu_call);
function [I] = menu_call(varargin)
S = guidata(gcbf);
switch gcbo
case S.um(1)
I = imread('grid.jpg');
case S.um(2)
I = imread('ConTrail.png');
case S.um(3)
I = imread('Opera.jpg');
case S.um(3)
I = imread('light wood.jpg');
end
set(Im,'cdata',I)
end
Lawson Hoover
on 9 Dec 2012
Ok fixed that missed point, but now I get the error: Undefined function or variable 'Im'.
Error in Beam_Deflection_GUI_3>menu_call (line 352)
set(Im,'cdata',I)
Error while evaluating uimenu Callback
That variable is created in the function above the call back with:
ImAxes = axes('Parent',S.fh,'units','normalized','Position',[0 0 1 1],'HitTest','off');
I = imread('ConTrail.png');
Im = imagesc(I,'HitTest','off');
colormap gray
set(ImAxes,...
'handlevisibility','off', ...
'visible','off');
And I stop the error by making the variable global but when that happens, the background image does not change, and it does not yield any errors.
Matt Fig
on 9 Dec 2012
Edited: Matt Fig
on 9 Dec 2012
But a subfunction has no access to variables created in the main function. Otherwise we wouldn't need to save S in guidata in the first place, then recall it in the subfunction! So you will notice that I saved the image handle in structure S as S.IH, like all data I will need in this callback or any other.
Lawson Hoover
on 9 Dec 2012
Ok, I am able to change to images now but instead of it being the background it is, the graph in which I graph data. And Id rather not have to load the clown first to get it to work.
code:
ImAxes = axes('Parent',S.fh,'units','normalized','Position',[0 0 1 1],'HitTest','off');
I = imread('curtain.jpg');
Im = imagesc(I,'HitTest','off');
colormap gray
set(ImAxes,...
'handlevisibility','off', ...
'visible','off');
X = load('clown');
cmenu = uicontextmenu;
bgmenu = uimenu(cmenu,'label','Background');
S.um(1) = uimenu(bgmenu,'Label','Grid');
S.um(2) = uimenu(bgmenu,'Label','ConTrail');
S.um(3) = uimenu(bgmenu,'Label','Opera');
S.um(4) = uimenu(bgmenu,'Label','Light Wood');
set(S.um,'CallBack',@menu_call_bg);
IMG = ind2rgb(X.X,X.map);
S.IH = image(IMG);
set(S.IH,'uicontextmenu',cmenu)
guidata(S.fh,S)
function [] = menu_call_bg(varargin)
S = guidata(gcbf);
switch gcbo
case S.um(1)
I = imread('grid.jpg');
case S.um(2)
I = imread('ConTrail.png');
case S.um(3)
I = imread('Opera.jpg');
case S.um(3)
I = imread('leaf.jpg');
end
set(S.IH,'cdata',I)
end
Matt Fig
on 9 Dec 2012
I think you need to slow down and think it through. You have all of the pieces to get this working but you haven't quite seen it yet. It seems like you are trying to rush through without understanding what is going on.
Why would you think you had to load clown every time to make your GUI work? I did that as an example because I don't know what images you have on your disk but I do know you have the sample images MATLAB came with!! Scroll up to the example I posted and look at the comments where I explain this clearly.
You need to make sure that S.IH is plotted on the correct axes the first time you create it. Then changing the cdata will not move it to another axes.
Lawson Hoover
on 9 Dec 2012
Edited: Lawson Hoover
on 9 Dec 2012
Ok so Im slowly getting it, you are loading clown and then saying it. But Clown is also a .mat right? so how would I save my images as a .mat? Also I have actually got the new image to appear on the back ground now, but instead of replacing it is just creating a new axes.
More Answers (0)
See Also
Categories
Find more on Interactive Control and Callbacks in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!An Error Occurred
Unable to complete the action because of changes made to the page. Reload the page to see its updated state.
Select a Web Site
Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .
You can also select a web site from the following list
How to Get Best Site Performance
Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.
Americas
- América Latina (Español)
- Canada (English)
- United States (English)
Europe
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom(English)
Asia Pacific
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)