Событие Matlab передается родителю

У меня есть пользовательский интерфейс, который я разработал, и я хочу, чтобы определенные нажатия клавиш инициировали какое-то действие в пользовательском интерфейсе. Я попытался определить функцию для обратного вызова keypressfcn фигуры, но если какой-либо другой элемент пользовательского интерфейса является активным элементом, вызывается keypressfcn для этого элемента (который пуст). Как я могу захватить нажатия клавиш для всей фигуры, не назначая один и тот же дескриптор функции keypressfcn всем дочерним элементам в пользовательском интерфейсе?


person user1207217    schedule 21.09.2012    source источник


Ответы (2)


Я обнаружил, что обратный вызов WindowKeyPressFcn делает то, что я хочу. Это свойство фигуры, но будьте осторожны, оно делает именно то, о чем говорит — фиксирует нажатия клавиш, пока это активная фигура (независимо от того, какой активный элемент). Подумайте, действительно ли вы этого хотите, например, когда элемент редактирования имеет фокус, WindowKeyPressFcn будет срабатывать при вводе.

person user1207217    schedule 24.09.2012

Боюсь, вам придется определять все без исключения uicontrol и 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

так что мой код остается читаемым.

person Rody Oldenhuis    schedule 21.09.2012