scenia
scenia

Reputation: 1629

Pressing a button disables keyboard input

I have a strange problem in my Matlab GUI. The GUI contains uipanel and icontrol objects, some of which are buttons. Usually, the GUI is controlled with the directional arrow keys.

However, once I click one of my buttons, the keyboard events are not recorded any more. I've set breakpoints in the keypress callback to find out what's happening and it turns out the callback is never called. If I manage to click the GUI background, it works once again, which makes me think it's related to the active control. But how can I give control back to the main window? uicontrol(hFigure) doesn't work, neither does figure(hFigure).

The following code snippet reproduces the problem. Copy it into a new file (ideally called test.m, otherwise Code Analyzer will complain) and run it to open a GUI window that shows this behaviour. Once the button is clicked, the arrow keys aren't recorded any more unless the user clicks the area outside the text uicontrol.

function test
    figure('KeyPressFcn',@key)
    clf
    p = uipanel('position',[0 0 1 1],'BackgroundColor',[.7 .7 .7]);
    uicontrol('Style','push','String','Click me','Units','norm',...
        'Position',[0.43 0.91 0.14 0.06],'Callback',@button);
    t = uicontrol(p,'Style','text','String','Use arrow keys','Units','norm',...
        'Position',[0.2 0.4 0.6 0.2],'FontSize',20);

    function button(~,~)
        set(t,'String','Button pressed.');
    end

    function key(~,e)
        set(t,'String',['Key ' e.Key ' pressed.']);
    end
end

Upvotes: 1

Views: 628

Answers (2)

mmagnuski
mmagnuski

Reputation: 1275

You could also set the WindowKeyPressFcn instead of KeyPressFcn.
For more information see my answer here:
matlab: difference between KeyPressFcn and WindowKeyPressFcn

Upvotes: 1

hoogamaphone
hoogamaphone

Reputation: 1102

You are right about why this doesn't work. When you click on the button, the figure is no longer the active control. The best way to fix this is to additionally set the KeyPressFcn property of the button to be the same as the KeyPressFcn of the figure.

function test
    figure('KeyPressFcn',@key)
    clf
    p = uipanel('position',[0 0 1 1],'BackgroundColor',[.7 .7 .7]);
    uicontrol('Style','push','String','Click me','Units','norm',...
        'Position',[0.43 0.91 0.14 0.06],'Callback',@button, ...
        'KeyPressFcn', @key);
    t = uicontrol(p,'Style','text','String','Use arrow keys','Units','norm',...
        'Position',[0.2 0.4 0.6 0.2],'FontSize',20);

    function button(~,~)
        set(t,'String','Button pressed.');
    end

    function key(~,e)
        set(t,'String',['Key ' e.Key ' pressed.']);
    end
end

Upvotes: 1

Related Questions