У меня есть пользовательский интерфейс, который я разработал, и я хочу, чтобы определенные нажатия клавиш инициировали какое-то действие в пользовательском интерфейсе. Я попытался определить функцию для обратного вызова keypressfcn фигуры, но если какой-либо другой элемент пользовательского интерфейса является активным элементом, вызывается keypressfcn для этого элемента (который пуст). Как я могу захватить нажатия клавиш для всей фигуры, не назначая один и тот же дескриптор функции keypressfcn всем дочерним элементам в пользовательском интерфейсе?
Событие Matlab передается родителю
Ответы (2)
Я обнаружил, что обратный вызов WindowKeyPressFcn делает то, что я хочу. Это свойство фигуры, но будьте осторожны, оно делает именно то, о чем говорит — фиксирует нажатия клавиш, пока это активная фигура (независимо от того, какой активный элемент). Подумайте, действительно ли вы этого хотите, например, когда элемент редактирования имеет фокус, WindowKeyPressFcn будет срабатывать при вводе.
Боюсь, вам придется определять все без исключения 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
так что мой код остается читаемым.