How can I relate a pushbutton to position?

1 view (last 30 days)
Hi! I'm making a piano on matlab & can't figure out how to have matlab recognize if the user pushed on a key based on the position of the key itself. Basically, if the user clicks on the right key I want a "Good Job" message to come up & "Error" message to come up if they click the wrong one. I'm thinking to use an if statement but everything I try isnt working. Here is my code so far:
%Paino Figure w/ pushbuttons
function PianoImage_HBraslawsce()
f=figure();
set(f, 'MenuBar','none'); %Remove menu bar
set(f,'NumberTitle','off');
set(f,'Name', 'Note Learner'); %Change name
%Each key as a pushbutton
KEYC = uicontrol('style','pushbutton','backgroundcolor',[1 1 1],'units','normalized','position',[.15 .15 .1 .45]);
KEYD = uicontrol('style','pushbutton','backgroundcolor',[1 1 1],'units','normalized','position',[.25 .15 .1 .45]);
KEYE = uicontrol('style','pushbutton','backgroundcolor',[1 1 1],'units','normalized','position',[.35 .15 .1 .45]);
KEYF = uicontrol('style','pushbutton','backgroundcolor',[1 1 1],'units','normalized','position',[.45 .15 .1 .45]);
KEYG = uicontrol('style','pushbutton','backgroundcolor',[1 1 1],'units','normalized','position',[.55 .15 .1 .45]);
KEYA = uicontrol('style','pushbutton','backgroundcolor',[1 1 1],'units','normalized','position',[.65 .15 .1 .45]);
KEYB = uicontrol('style','pushbutton','backgroundcolor',[1 1 1],'units','normalized','position',[.75 .15 .1 .45]);
KEYCHI = uicontrol('style','pushbutton','backgroundcolor',[1 1 1],'units','normalized','position',[.85 .15 .1 .45]);
KEYCSH = uicontrol('style','pushbutton','backgroundcolor',[0 0 0],'units','normalized','position',[.20 .3 .08 .3]);
KEYEb=uicontrol('style','pushbutton','backgroundcolor',[0 0 0],'units','normalized','position',[.30 .3 .08 .3]);
KEYFSH=uicontrol('style','pushbutton','backgroundcolor',[0 0 0],'units','normalized','position',[.5 .3 .08 .3]);
KEYAb=uicontrol('style','pushbutton','backgroundcolor',[0 0 0],'units','normalized','position',[.60 .3 .08 .3]);
KEYBb=uicontrol('style','pushbutton','backgroundcolor',[0 0 0],'units','normalized','position',[.70 .3 .08 .3]);
%Keys callback
set(KEYC,'Callback',{@keypressed,KEYC,KEYCSH,KEYD,KEYE,KEYEb,KEYF,KEYFSH,KEYG,KEYA,KEYAb,KEYB,KEYBb,KEYCHI})
set(KEYCSH,'Callback',{@keypressed,KEYC,KEYCSH,KEYD,KEYE,KEYEb,KEYF,KEYFSH,KEYG,KEYA,KEYAb,KEYB,KEYBb,KEYCHI})
set(KEYD,'Callback',{@keypressed,KEYC,KEYCSH,KEYD,KEYE,KEYEb,KEYF,KEYFSH,KEYG,KEYA,KEYAb,KEYB,KEYBb,KEYCHI})
set(KEYE,'Callback',{@keypressed,KEYC,KEYCSH,KEYD,KEYE,KEYEb,KEYF,KEYFSH,KEYG,KEYA,KEYAb,KEYB,KEYBb,KEYCHI})
set(KEYEb,'Callback',{@keypressed,KEYC,KEYCSH,KEYD,KEYE,KEYEb,KEYF,KEYFSH,KEYG,KEYA,KEYAb,KEYB,KEYBb,KEYCHI})
set(KEYF,'Callback',{@keypressed,KEYC,KEYCSH,KEYD,KEYE,KEYEb,KEYF,KEYFSH,KEYG,KEYA,KEYAb,KEYB,KEYBb,KEYCHI})
set(KEYFSH,'Callback',{@keypressed,KEYC,KEYCSH,KEYD,KEYE,KEYEb,KEYF,KEYFSH,KEYG,KEYA,KEYAb,KEYB,KEYBb,KEYCHI})
set(KEYG,'Callback',{@keypressed,KEYC,KEYCSH,KEYD,KEYE,KEYEb,KEYF,KEYFSH,KEYG,KEYA,KEYAb,KEYB,KEYBb,KEYCHI})
set(KEYAb,'Callback',{@keypressed,KEYC,KEYCSH,KEYD,KEYE,KEYEb,KEYF,KEYFSH,KEYG,KEYA,KEYAb,KEYB,KEYBb,KEYCHI})
set(KEYA,'Callback',{@keypressed,KEYC,KEYCSH,KEYD,KEYE,KEYEb,KEYF,KEYFSH,KEYG,KEYA,KEYAb,KEYB,KEYBb,KEYCHI})
set(KEYBb,'Callback',{@keypressed,KEYC,KEYCSH,KEYD,KEYE,KEYEb,KEYF,KEYFSH,KEYG,KEYA,KEYAb,KEYB,KEYBb,KEYCHI})
set(KEYB,'Callback',{@keypressed,KEYC,KEYCSH,KEYD,KEYE,KEYEb,KEYF,KEYFSH,KEYG,KEYA,KEYAb,KEYB,KEYBb,KEYCHI})
set(KEYCHI,'Callback',{@keypressed,KEYC,KEYCSH,KEYD,KEYE,KEYEb,KEYF,KEYFSH,KEYG,KEYA,KEYAb,KEYB,KEYBb,KEYCHI})
end
function keypressed(x,y,KEYC,KEYCSH,KEYD,KEYE,KEYEb,KEYF,KEYFSH,KEYG,KEYA,KEYAb,KEYB,KEYBb,KEYCHI)
x;
y;
KEYC;
KEYCSH;
KEYD;
KEYE;
KEYEb;
KEYF;
KEYFSH;
KEYG;
KEYA;
KEYAb;
KEYB;
KEYBb;
KEYCHI;
KEYC='C';
KEYCSH='C#';
KEYD='D';
KEYE='E';
KEYEb='Eb';
KEYF='F';
KEYFSH='F#';
KEYG='G';
KEYA='A';
KEYAb='Ab';
KEYB='B';
KEYBb='Bb';
KEYCHI='C(high)';
'C'=='position',[.15 .15 .1 .45];
'C#'=='position',[.20 .3 .08 .3];
'D'=='position',[.25 .15 .1 .45];
'E'=='position',[.35 .15 .1 .45];
'Eb'=='position',[.30 .3 .08 .3];
'F'=='position',[.45 .15 .1 .45];
'F#'=='position',[.5 .3 .08 .3];
'G'=='position',[.55 .15 .1 .45];
'Ab'=='position',[.60 .3 .08 .3];
'A'=='position',[.65 .15 .1 .45];
'Bb'=='position',[.70 .3 .08 .3];
'B'=='position',[.75 .15 .1 .45];
'C(high)'=='position',[.85 .15 .1 .45];
end
  2 Comments
Christophe
Christophe on 28 Apr 2020
Edited: Christophe on 28 Apr 2020
I do not understand what you are trying to do.
The code at the bottom from the line
C'=='position',[.15 .15 .1 .45];
is not correct.
Anyway, in your x variable, you have the uicontrol handle. You have access to all the uicontrol properties of the button you push.
Han
Han on 28 Apr 2020
I'm going to have the letters pop up on the screen and the user has to click the correct key based off of that letter. I honestly have no clue what I'm doing and thought relating the position of the button to the letter would be correct.

Sign in to comment.

Accepted Answer

Geoff Hayes
Geoff Hayes on 28 Apr 2020
Han - try using the UserData property of the pushbutton to store the key that the button represents. That way, when the button is pressed and the callback fires, you can use (get) this property to compare against the letters that have popped up on screen. Your code could look something like
function PianoImage_HBraslawsce()
f=figure();
set(f, 'MenuBar','none'); %Remove menu bar
set(f,'NumberTitle','off');
set(f,'Name', 'Note Learner'); %Change name
%Each key as a pushbutton
KEYC = uicontrol('style','pushbutton','backgroundcolor',[1 1 1],'units','normalized',...
'position',[.15 .15 .1 .45], 'UserData', 'C','Callback',@keypressed);
KEYD = uicontrol('style','pushbutton','backgroundcolor',[1 1 1],'units','normalized',...
'position',[.25 .15 .1 .45], 'UserData', 'D','Callback',@keypressed);
KEYE = uicontrol('style','pushbutton','backgroundcolor',[1 1 1],'units','normalized',...
'position',[.35 .15 .1 .45], 'UserData', 'E','Callback',@keypressed);
KEYF = uicontrol('style','pushbutton','backgroundcolor',[1 1 1],'units','normalized',...
'position',[.45 .15 .1 .45], 'UserData', 'F','Callback',@keypressed);
KEYG = uicontrol('style','pushbutton','backgroundcolor',[1 1 1],'units','normalized',...
'position',[.55 .15 .1 .45], 'UserData', 'G','Callback',@keypressed);
KEYA = uicontrol('style','pushbutton','backgroundcolor',[1 1 1],'units','normalized','position',[.65 .15 .1 .45], 'UserData', 'A','Callback',@keypressed);
KEYB = uicontrol('style','pushbutton','backgroundcolor',[1 1 1],'units','normalized',...
'position',[.75 .15 .1 .45], 'UserData', 'B','Callback',@keypressed);
KEYCHI = uicontrol('style','pushbutton','backgroundcolor',[1 1 1],'units','normalized',...
'position',[.85 .15 .1 .45], 'UserData', 'C(high)','Callback',@keypressed);
KEYCSH = uicontrol('style','pushbutton','backgroundcolor',[0 0 0],'units','normalized',...
'position',[.20 .3 .08 .3], 'UserData', 'C#','Callback',@keypressed);
KEYEb=uicontrol('style','pushbutton','backgroundcolor',[0 0 0],'units','normalized',...
'position',[.30 .3 .08 .3], 'UserData', 'Eb','Callback',@keypressed);
KEYFSH=uicontrol('style','pushbutton','backgroundcolor',[0 0 0],'units','normalized',...
'position',[.5 .3 .08 .3], 'UserData', 'F#','Callback',@keypressed);
KEYAb=uicontrol('style','pushbutton','backgroundcolor',[0 0 0],'units','normalized',...
'position',[.60 .3 .08 .3], 'UserData', 'Ab','Callback',@keypressed);
KEYBb=uicontrol('style','pushbutton','backgroundcolor',[0 0 0],'units','normalized',...
'position',[.70 .3 .08 .3], 'UserData', 'Bb','Callback',@keypressed);
function keypressed(hObject, eventdata)
fprintf('You have pressed key %s\n', get(hObject, 'UserData'));
end
end
I've nested the callback within the main function for convenience but also just in case you need to access those variables declared there. This avoids the need to pass the button handles into the callback function whose signature has now been reduced to simply
function keypressed(hObject, eventdata)
In your callback you were overwriting the pushbutton handle inputs with strings (this isn't something you really want or should do as you are changing the purpose of the variable from a function handle to a string). These strings are now stored in the UserData property for each button. We can then use the get function to retrieve that key string.
Note that when comparing this string against whatever note you've displayed, you will want to use the strcmp function (using == with strings will generally only work if the strings being compared have the same number of characters).
  14 Comments
Geoff Hayes
Geoff Hayes on 1 May 2020
Yes, I forgot a line (in the callback) to update the sharedData structure
function keypressed(hObject, eventdata, hFig) %callback for key clicked
sharedData = guidata(hFig);
if strcmp(sharedData.random1{sharedData.atKey1}, get(hObject, 'UserData'))==1 %<SM:ROP>
(msgbox('Good Job!'));
sharedData.atKey1 = sharedData.atKey1 + 1; %<SM:RTOTAL>
if sharedData.atKey1 > length(sharedData.random1)
(msgbox('Good Job! You have completed the round. Start over to keep on learning!'));
end
else
msgbox('ERROR. Please try again.');
end
guidata(hFig, sharedData); % <---- need to update the sharedData structure
end
Han
Han on 1 May 2020
Thank you so much! It works now

Sign in to comment.

More Answers (0)

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!