matlab按键FCN用于按住键

matlab按键FCN用于按住键,matlab,Matlab,我想只允许用户在按住控制键(按下)时缩放。我在WindowKeyPressFcn回调函数中实现了以下功能: function keypress_callback(obj, evd, hZoom) switch evd.Key case 'control' set(hZoom,'Enable','on'); end %disp(evd); % used for debugging purposes 此函数接受在激活回调函数时从主程序传递的缩放对象句柄(hZoom)(set(hFigu

我想只允许用户在按住控制键(按下)时缩放。我在
WindowKeyPressFcn
回调函数中实现了以下功能:

function keypress_callback(obj, evd, hZoom)
switch evd.Key
  case 'control'
    set(hZoom,'Enable','on');
end
%disp(evd); % used for debugging purposes
此函数接受在激活回调函数时从主程序传递的缩放对象句柄(
hZoom
)(
set(hFigure,'WindowKeyPressFcn',{@keypress\u callback,hZoom});
)。我编写了一个类似的
WindowKeyReleaseFcn
(通过
set(hFigure,'WindowKeyReleaseFcn',{@keyrelease_callback,hZoom})设置)
)在释放控件时禁用缩放

function keyrelease_callback(obj, evd, hZoom)
switch evd.Key
  case 'control'
    set(hZoom,'Enable','off');
end
%disp(evd); % used for debugging purposes
目标是仅在按下
Ctrl
键时才允许正常的缩放行为(单击可按因子放大;按住shift键单击可按因子缩小;拖动单击可放大选定区域)。一旦这个修改键被释放,缩放功能应该被禁用

但是,此行为无法按预期工作。简单地测试(通过
disp(evd)
)是否按下一个键,可以发现任意键都可以按任意数量的键;但是,如果按下的键是
Ctrl
,则只能按一次这样的键,所有后续按下的
Ctrl
都将被忽略,而任何其他键的所有后续按下都会导致该键出现在Matab命令窗口中,而不会触发
keypress\u回调
功能。因此,按下
Ctrl
似乎会以某种方式禁用
keypress\u callback
功能,可能是因为焦点从图形转移到缩放对象?作为一个必然的问题,
WindowKeyReleaseFcn
对于非修改键(evd显示正确的已释放键)似乎可以正常工作,但是如果已释放键是非修改键,
evd
中的
键是空的


如果有人能够演示所设想的依赖于控件的缩放行为的正确实现,我将不胜感激。

更现代的方式似乎是:

gca
zoom on
z = zoom(gcf);
set(z, 'ButtonDownFilter', @ZoomGate)
其中
ZoomGate.m
包含如下内容:

function inhibitZoom = ZoomGate(varargin)

if ismember('control', get(gcbo,'currentModifier'))
    inhibitZoom = 0;
else
    inhibitZoom = 1;
end
根据提问者的评论进行编辑:


我的第一个建议是使用
WindowButtonDownFcn
回调,如果检测到控件修饰符,它会调用
zoom
本身。如果您可以控制
缩放
实现,则这很好。回顾我的代码(我在15年前做过类似的事情),我发现它过去很简单-
zoom
是一个m文件,有一个很明显的命名方式:
zoom down
意思是“按钮刚刚按下”。然后,就这样,MathWorks移动了球门柱并改变了缩放。看起来我当时的反应是以更旧、更简单的风格重新实现我自己的
zoom
。没有帮助,除非你真的想要那个代码(让我知道)。

在我的Linux系统上,按control键也会导致
alt
gcbo
返回(shift变为
extend
,alt变为nothing)。如果快速单击鼠标,则无论按住哪个键(或没有按住任何键),由
gcbo
返回的值都是
open
。你知道这意味着什么吗?在我开始尝试使用
WindowKeyPressFcn
WindowKeyReleaseFcn
实现上述行为之前,正如你所建议的,我正在尝试使用
WindowButtonDownFcn
实现。为了获得按下的控制键,我使用了
modifiers=get(obj,'currentModifier');ctrlIsPressed=ismember('control',修饰符)
你知道这种方法(
get(obj,'currentModifier')
)是否等同于你的方法(
get(gcbo,'SelectionType'
)?采用
gcbo
方法后的行为如下:初始ctrl+单击激活
zoom
对象(通过
set(hZoom,'Enable','on')
)但是单击本身被丢弃(因此实际上没有进行缩放)。随后单击会像平常一样缩放,但缩放永远不能被禁用(尽管包括
set(hZoom,'Enable','off'))
在gbco
/
alt
比较语句的
else
语句中。缩放对象在整个脚本期间保持激活状态。我已更改了答案。要回答您在注释中提出的问题:(1)是,用于检测控件修饰符
ismember('control',获取(gcbo,'CurrentModifier'))
可能比使用
isequal(get(gcbo,'SelectionType'),'alt')
更干净、更健壮。这也是一个遗留代码问题。(2)是的,SelectionType
'open'
指的是双击。比如,你知道,双击“打开”有些东西。我知道。但是如果你足够努力的话,到处都有逻辑。再次感谢你的帮助。我无法让示例代码正常工作。根据,我尝试了一些变化,比如在函数定义中将返回值括在方括号中(即,
[inhibitZoom]
)使用逻辑布尔表达式或字符串,如
true
false
'true'
'false'
,而不是
0
1
,但这些变化都不会导致依赖于控件的缩放。实际上,
按钮下过滤器
函数甚至似乎都无法访问(我在其中放置了简单的
disp
命令,以便在调用时发出警报)。