How to design GUI buttons?
21 次查看(过去 30 天)
显示 更早的评论
Hello everyone.
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/297108/image.jpeg)
How can I design a GUI button like the picture above? With logos and text beside the logo? Thanks in advance.
2 个评论
Mohammad Sami
2020-5-22
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.
采纳的回答
Tommy
2020-5-28
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 个评论
Tommy
2020-6-4
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.
更多回答(0 个)
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Interactive Control and Callbacks 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!