MATLAB: How do I Assign Push Buttons to Values so that I can Track the Data??
7 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
Emeka Anekwe
el 24 de Jul. de 2015
Comentada: Joe
el 16 de Ag. de 2015
Hello,
For clarity, I will explain my project:
I need to create a UI where participants can listen to two versions of a speech shaped noise (2 .wav files) and choose which one they think sounds the best. I then need to collect the data on the user responses.
My progress:
I used GUIDE to create an interface with two push buttons that is presented AFTER listening to the sounds. Here is the code for one of the .m files I'm using:
function varargout = simple_gui(varargin)
gui_Singleton = 1;
gui_State = struct('gui_Name', mfilename, ...
'gui_Singleton', gui_Singleton, ...
'gui_OpeningFcn', @simple_gui_OpeningFcn, ...
'gui_OutputFcn', @simple_gui_OutputFcn, ...
'gui_LayoutFcn', [] , ...
'gui_Callback', []);
if nargin && ischar(varargin{1})
gui_State.gui_Callback = str2func(varargin{1});
end
if nargout
[varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
gui_mainfcn(gui_State, varargin{:});
function simple_gui_OpeningFcn(hObject, eventdata, handles, varargin)
handles.output = hObject;
guidata(hObject, handles);
function varargout = simple_gui_OutputFcn(hObject, eventdata, handles)
varargout{1} = handles.output;
handles.output = hObject;
function pushbutton1_Callback(hObject, eventdata, handles)
function pushbutton3_Callback(hObject, eventdata, handles)
Where I need help:
I am having trouble assigning both push buttons as different values (like 1 and 2) and have the data represented in a clean way. If I could plot them on a bar graph, that would be an added plus.
Thanks!
0 comentarios
Respuesta aceptada
Joe
el 24 de Jul. de 2015
Editada: Joe
el 24 de Jul. de 2015
If you are going to be programming a GUI, I strongly recommend that you acquaint yourself with the basics of MATLAB's object-oriented capabilities. OOP is not the end-all-be-all of programming as most CS people would have us believe, but is definitely the way to go when making a GUI. Here is a minimal example that does what you need; it stores the number of button presses as an object property which can be accessed from any other method in the class. You can run this as a standalone .m file without needing a wrapper script or anything. (Sorry that I tend to write lines a bit longer than desirable...)
classdef simple_gui < handle % Make sure to inherit from handle class
properties
f; % Holds figure
width = 400; % Panel width
height = 500; % Panel height
mainPanel; % Main GUI panel
playSoundButton;
response1Button;
response2Button;
nResponse1 = 0; % Track response 1
nResponse2 = 0; % Track response 2
end
methods
function obj = simple_gui
% Create figure, hide during creation
obj.f = figure('Visible', 'off', 'Position', [400, 500, obj.width, obj.height], ...
'resize', 'off', 'NumberTitle', 'off');
% Create Main Panel
k = obj.width/obj.height;
obj.mainPanel = uipanel('FontSize',12, 'units', 'normalized', 'fontweight', 'bold', ...
'Position',[0.025*[1, k], ...
[(1 - 2*0.025), (1 - 2*k*0.025)]]);
% Create Buttons
buttonWidth = 0.25; buttonHeight = 0.15;
obj.playSoundButton = uicontrol('style', 'pushbutton', 'Parent', obj.mainPanel, ...
'Units', 'normalized', 'Position', [0.1, 0.5, buttonWidth, buttonHeight], ...
'String', 'Play Sound', 'Callback', @obj.playSound);
obj.response2Button = uicontrol('style', 'pushbutton', 'Parent', obj.mainPanel, ...
'Units', 'normalized', 'Position', [0.4, 0.5, buttonWidth, buttonHeight], ...
'String', 'Response 1', 'Callback', @obj.response1);
obj.response2Button = uicontrol('style', 'pushbutton', 'Parent', obj.mainPanel, ...
'Units', 'normalized', 'Position', [0.7, 0.5, buttonWidth, buttonHeight], ...
'String', 'Response 2', 'Callback', @obj.response2);
% Assign a name to appear in the window title.
set(obj.f, 'Name', 'Sound Survey Tool');
% Move the window to the center of the screen.
movegui(obj.f,'center')
% Set GUI as visible
set(obj.f, 'Visible', 'on');
end
%%%CALLBACK FUNCTIONS
function playSound(obj, eventData, handles) %#ok eventData and handles are unused
fprintf('Sound played\n');
% Code to play sound goes here
end
function response1(obj, ~, ~)
obj.nResponse1 = obj.nResponse1 + 1;
fprintf('Response 1 selected; response 1 count = %i\n', obj.nResponse1);
end
function response2(obj, ~, ~)
obj.nResponse2 = obj.nResponse2 + 1;
fprintf('Response 2 selected; response 2 count = %i\n', obj.nResponse2);
end
end
end
In my opinion, this is much more readable than the functional style GUIDE uses, and it is much, much easier to store data for access later. I've been writing GUI's with OOP for about a year now and forgotten most of what I knew about the function-based approach, so I'm afraid I can't help you if you want to go with that route.
Más respuestas (1)
Emeka Anekwe
el 14 de Ag. de 2015
1 comentario
Joe
el 16 de Ag. de 2015
So is the main issue the "flow control" of the GUI, i.e. how to tell when you've moved from one sound to the next, and one user to the next? I'm going to assume that's the case, correct me otherwise.
- To handle sound advancement, your "play sound" button can track an index of which sound to play; it can be advanced each time the button is pressed. This will also index the rows of your results matrix. Every time the GUI moves to the next user, reset the sound index.
- I would add a "next user" button the GUI as well -- you could have the "play sound" button perform that function if desired -- and add a corresponding "user index" as an object property to keep track of the column index on users.
This might also be a good time to make use of a structure array , especially if there are other user data you want to keep track of.
Finally, always overestimate the ability of your users to screw up your GUI, especially one that relies on careful flow control. I'd recommend you make heavy use of the "enable" feature to turn off buttons as necessary - for example, disable the "voting" buttons until a sound has finished playing. The pre-2014b call for that is
set(button, 'enable', 'off');
or
set(button, 'enable', 'on');
I think this syntax works in new versions as well but there is also a more OOP-like interface that will do the same thing; I haven't gotten familiar with it.
Hope this helps.
Ver también
Categorías
Más información sobre Data Type Identification en Help Center y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!