MATLAB: How do I Assign Push Buttons to Values so that I can Track the Data??
    10 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
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!

