How to design GUI buttons?

조회 수: 39 (최근 30일)
John Doe
John Doe 2020년 5월 21일
댓글: Tommy 2020년 6월 4일
Hello everyone.
How can I design a GUI button like the picture above? With logos and text beside the logo? Thanks in advance.
  댓글 수: 2
Mohammad Sami
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.
John Doe
John Doe 2020년 5월 23일
I want it in GUIDE, not app designer.

댓글을 달려면 로그인하십시오.

채택된 답변

Tommy
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
John Doe
John Doe 2020년 6월 3일
Hey Tommy. Thanks for the prompt reply.
What I meant is in my GUIDE, I already have a set of pushbuttons, let's say p1 and p2 with tag p1 and p2. How can I change the icon of them?
From your code, it seems like (my guess) you are programmatically creating the pushbuttons?
p = uicontrol('Style', 'pushbutton',...
'Position', [100, 150, 100, 30],...
'String', 'Pears',...
'Tag', 'whatever'); % <- here
Will this set of code will solve my problem? Kinda confused here.
A small example will surely help me, if that's not such a big of a deal for you.
Tommy
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 CenterFile Exchange에서 Interactive Control and Callbacks에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by