3

我有一个我设计的用户界面,我希望让某些按键在用户界面中启动一些操作。我尝试为图形的 keypressfcn 回调定义一个函数,但如果任何其他 UI 元素是活动元素,则调用该元素的 keypressfcn(为空)。如何在不为 UI 中的所有子元素分配相同的 keypressfcn 函数句柄的情况下捕获整个图形的按键?

4

2 回答 2

3

我发现 WindowKeyPressFcn 回调做了我想要的。这是图形的一个属性,但要注意,它完全按照它所说的去做 - 它在这是活动图形时捕获按键(不管活动元素是什么)。考虑一下你是否真的想要这个,例如当一个编辑元素有焦点时,WindowKeyPressFcn 将在它被输入时触发。

于 2012-09-24T15:26:57.043 回答
2

恐怕你必须定义每一个uicontrol's KeyPressFcn。想一想:如果您设计了 Matlab,您将如何同时保持选项开放,让用户为不同的 分配不同的按键功能uicontrols,同时还允许他们对所有人只使用一个主功能uicontrols

每个新人uicontrol都必须知道你想这样做,这等于分配它的KeyPressFcn.

最简单的方法是编写一些通用函数,例如

function KeyPressFcnFwd(obj,event)
    prn = get(obj, 'parent')
    fcn = get(prn, 'KeyPressFcn');
    fcn(prn,event); 
end

然后像这样定义uicontrols:

button = uicontrol(...
    'style', 'pushbutton', ...
    ...
    'KeyPressFcn', @KeyPressFcnFwd);

这样做会使某个单选按钮上的按键调用其父级的 KeyPressFcn,这是一个单选组,后者又将呼叫转发到其父级的KeyPressFcn,这是一个 uipanel,后者又将呼叫转发到其父级的KeyPressFcn,最后是你的身影KeyPressFcn

简而言之:无论你uicontrol的嵌套有多深,调用总是会一直转发到图上。

如果将此函数定义为创建“主”图形的函数中的嵌套函数,则可以更有效地完成所有操作:

function main %# toplevel function

    ...

    mainFig = figure(...)  %# your main figure

    ...

    %# nested function 
    function KeyPressFcnFwd(obj,event)            
        fcn = get(mainFig, 'KeyPressFcn');
        fcn(mainFig,event); 
    end

    ...

    %# Function to build the GUI
    %# can be a subfunction, nested function or external function
    populateMainWin(mainFig, @KeyPressFcnFwd); 

    ...


end

这样你就没有调用整个树的开销KeyPressFcn

在可能有很多样板的情况下(这是一个很好的候选),我通常定义一些速记,比如

 function handle = uibutton(parent, text, varargin)

     handle = uicontrol(...
        'parent', parent, ...
        'style' , 'pushbutton', ...
        'units' , 'normalized', ...
        'string', text, ...
        'KeyPressFcn', @KeyPressFcnFwd, ...
        varargin{:});

 end

这样我的代码仍然可读。

于 2012-09-21T15:24:25.723 回答