필터 지우기
필터 지우기

How can I relate a pushbutton to position?

조회 수: 3 (최근 30일)
Han
Han 2020년 4월 28일
댓글: Han 2020년 5월 1일
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
Christophe
Christophe 2020년 4월 28일
편집: Christophe 2020년 4월 28일
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 2020년 4월 28일
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.

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

채택된 답변

Geoff Hayes
Geoff Hayes 2020년 4월 28일
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
Geoff Hayes
Geoff Hayes 2020년 5월 1일
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 2020년 5월 1일
Thank you so much! It works now

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

추가 답변 (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