How to design GUI buttons?
25 views (last 30 days)
Show older comments
Hello everyone.
How can I design a GUI button like the picture above? With logos and text beside the logo? Thanks in advance.
2 Comments
Mohammad Sami
on 22 May 2020
In App Designer, the uibutton have a property called Icon. You can set the Icon property to show an image.
If you want to group the buttons together, then use uitogglebutton with uibuttongroup.
Accepted Answer
Tommy
on 28 May 2020
You can set the CData of a uicontrol pushbutton:
p = uicontrol('Style', 'pushbutton', 'Position', [100, 150, 100, 30], 'String', 'Pears');
% background
icon = 130*ones([p.Position([4 3]),3], 'uint8'); % dark gray border
icon(2:end-1,2:end-1,:) = 240; % lighter gray top half
icon(end/2+1:end-3,4:end-3,:) = 225; % medium gray bottom half
icon(2,2,:) = icon(1,1,:); icon(1,1,:) = 240; % rounded upper left edge
icon(2,end-1,:) = icon(1,end,:); icon(1,end,:) = 240; % rounded upper right edge
icon(end-1,2,:) = icon(end,1,:); icon(end,1,:) = 240; % rounded lower left edge
icon(end-1,end-1,:) = icon(end,end,:); icon(end,end,:) = 240; % rounded lower right edge
% image
img = imread('pears.png');
icon(6:25, 6:25, :) = imresize(img, [20, 20]); % place picture on background
p.CData = icon;
If you are creating many similar buttons, you might create a function which accepts the rgb values for the image and spits out the CData. And of course, you can move the image within the background. The above code just places it on the left side of the button with 5 pixels separating it from the edges.
5 Comments
Tommy
on 4 Jun 2020
Ah okay I see. That code does create a new pushbutton, named p. If you already have pushbuttons, you can definitely use them instead, but you'll have to find them. Possibly like this:
p1 = findobj('Tag', 'p1');
Then the rest of the code would be the same.
So for example, suppose you've created two buttons, with tags 'p1' and 'p2':
fig = figure;
uicontrol(fig,...
'Style', 'pushbutton',...
'Position', [100, 150, 100, 30],...
'String', 'Pears',...
'Tag', 'p1');
uicontrol(fig,...
'Style', 'pushbutton',...
'Position', [100, 190, 100, 30],...
'String', 'Peppers',...
'Tag', 'p2');
Elsewhere, you can use findobj to retrieve each button and assign its CData, possibly with another function getIcon() to do the dirty work:
tags = {'p1', 'p2'};
files = {'pears.png', 'peppers.png'};
for i = 1:numel(tags)
button = findobj('Tag', tags{i});
img = imread(files{i});
button.CData = getIcon(button, img);
end
function icon = getIcon(button, img)
% background
icon = 130*ones([button.Position([4 3]),3], 'uint8'); % dark gray border
icon(2:end-1,2:end-1,:) = 240; % lighter gray top half
icon(end/2+1:end-3,4:end-3,:) = 225; % medium gray bottom half
icon(2,2,:) = icon(1,1,:); icon(1,1,:) = 240; % rounded upper left edge
icon(2,end-1,:) = icon(1,end,:); icon(1,end,:) = 240; % rounded upper right edge
icon(end-1,2,:) = icon(end,1,:); icon(end,1,:) = 240; % rounded lower left edge
icon(end-1,end-1,:) = icon(end,end,:); icon(end,end,:) = 240; % rounded lower right edge
% image
icon(6:25, 6:25, :) = imresize(img, [20, 20]); % place picture on background
end
If all of your buttons are exactly the same size, you could probably avoid recreating the background each time.
Here is a simple example for changing the figure's motion callback:
% somewhere...
fig = figure;
uicontrol(fig,...
'Style', 'pushbutton',...
'Position', [100, 150, 100, 30],...
'String', 'Pears',...
'Tag', 'p1');
uicontrol(fig,...
'Style', 'pushbutton',...
'Position', [100, 190, 100, 30],...
'String', 'Peppers',...
'Tag', 'p2');
and
% maybe somewhere else...
tags = {'p1', 'p2'};
files = {'pears.png', 'peppers.png'};
for i = 1:numel(tags)
button = findobj('Tag', tags{i});
img = imread(files{i});
[button.CData, button.UserData] = getIcon(button, img);
end
function [icon, blueIcon] = getIcon(button, img)
% background
icon = 130*ones([button.Position([4 3]),3], 'uint8'); % dark gray border
icon(2:end-1,2:end-1,:) = 240; % lighter gray top half
icon(end/2+1:end-3,4:end-3,:) = 225; % medium gray bottom half
icon(2,2,:) = icon(1,1,:); icon(1,1,:) = 240; % rounded upper left edge
icon(2,end-1,:) = icon(1,end,:); icon(1,end,:) = 240; % rounded upper right edge
icon(end-1,2,:) = icon(end,1,:); icon(end,1,:) = 240; % rounded lower left edge
icon(end-1,end-1,:) = icon(end,end,:); icon(end,end,:) = 240; % rounded lower right edge
% alternate background
blueIcon = icon;
blueIcon(2:end-1,2:end-1,3) = blueIcon(2:end-1,2:end-1,3) + 15;
% image
icon(6:25, 6:25, :) = imresize(img, [20, 20]); % place picture on background
blueIcon(6:25, 6:25, :) = imresize(img, [20, 20]);
end
and
% possibly a third location...
tags = {'p1', 'p2'};
fig.WindowButtonMotionFcn = {@moveCallback, tags};
function moveCallback(src, ~, tags)
cPos = src.CurrentPoint;
% To store previous state, so that buttons are not updated every single time this
% function is called:
persistent wasInRect;
if isempty(wasInRect)
wasInRect = false(numel(tags),1);
end
for i = 1:numel(tags)
button = findobj('Tag', tags{i});
% Determine if mouse is on button:
bPos = button.Position;
isInRect = inpolygon(cPos(1), cPos(2), [bPos(1), bPos(1)+bPos(3)], [bPos(2), bPos(2)+bPos(4)]);
% Update button's CData, if necessary:
if (isInRect && ~wasInRect(i)) || (~isInRect && wasInRect(i))
flipCData(button);
wasInRect(i) = ~wasInRect(i);
end
end
function flipCData(button)
altIcon = button.UserData;
button.UserData = button.CData;
button.CData = altIcon;
end
end
You might want to adjust the colors somewhat. There may be better alternatives to using each button's UserData, but I think this at least illustrates the general idea.
More Answers (0)
See Also
Categories
Find more on Migrate GUIDE Apps 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!