NSView 无法检测到鼠标移动事件

问题描述 投票:0回答:3

我正在尝试制作一个简单的应用程序,其中有一个空的红色矩形,每当鼠标移动到矩形的上半边框时,光标就会变成闭合的手。

我从选择基础命令行项目开始。制作了一个透明的

NSWindow
,并用矩形在其中嵌入了
NSView
,制作了窗口来接受鼠标移动事件(通过方法:
-setAcceptsMouseMovedEvents
)。我已覆盖
-canBecomeKeyWindow
-canBecomeMainWindow
窗口以返回 YES。但不知何故,
-mouseMoved
没有收到任何
NSView
事件。

当我通过制作可可应用程序项目并在

-applicationDidFinishLaunching
方法中创建窗口来放置相同的代码时,我的视图能够接收
-mouseMoved
事件。

为什么当我使用基础命令行实用项目时它没有接收到鼠标移动事件?

我还观察到,每当我通过基础命令行实用程序项目创建一个窗口(carbon 或 cocoa)时,即使单击标题栏,该窗口也不会成为关键。单击标题栏时,标题栏颜色保持浅灰色而不是变暗灰色的。为什么会发生这种情况?

我已覆盖

-canBecomeKeyWindow
-canBecomeMainWindow
NSwindow
以返回 YES。

cocoa macos
3个回答
13
投票

我同意约书亚已经说过的话。任何要显示用户界面的应用程序,无论是不露面的后台进程还是显示在 Dock 中的进程,都应该采用应用程序包的形式,而不是像 Foundation 工具模板那样的普通旧式 Mach-O 可执行文件。创建。

此外,视图默认不响应

mouseMoved:
事件也是有原因的:

  1. 鼠标移动事件会快速淹没事件队列
  2. 通常没有什么理由使用
    mouseMoved:
    ,因为跟踪区域 更加有效和高效。

不久前,我编写了一个小测试应用程序来演示这两种方法之间的差异:

alt text

在上视图中移动鼠标大约 20 秒会产生 1000 个事件,而在使用跟踪区域的下视图中,会产生不到 50 个事件。

示例 GitHub 项目:https://github.com/NSGod/MouseMoved-vs-TrackingAreas

再次,正如约书亚提到的,如果您能够描述您想要完成的任务,将会很有帮助。如果您的应用程序需要成为后台应用程序(LSUIElement == 1),并呈现一个界面而不出现在 Dock 中,那么有一些方法可以做到这一点(正如 Josh 提到的,命令行、非捆绑应用程序不是方式)。


3
投票

您没有事件循环来检测事件并将它们传递到您的窗口,因为您的程序没有启动 NSApplication。请参阅典型 Cocoa 应用程序的 main.m 文件。

描述您试图通过采用这种方法实现的目标可能会有所帮助。我的猜测是您正在构建一个守护进程,但想要一个 GUI 界面来管理“无头”守护进程。或者您正在构建一个新的登录管理系统。无论哪种情况,都有特定的方法可以同时完成这两者,但不是这样。 :-)


0
投票

要使您的

NSView
检测 mouseMoved 事件,您必须执行以下操作:

  1. 覆盖 NSView 子类中的
    acceptsFirstResponder
    属性
  2. 覆盖 NSView 子类中的
    mouseMoved
    事件
  3. 将视图窗口设置为
    acceptMouseMovedEvents = YES

@implementation YourNSView

- (BOOL) acceptsFirstResponder {
  return YES;
}

- (void) mouseMoved:(NSEvent*) event {
  // can't hear these events? did you override acceptsFirstResponder!
  [super mouseMoved:event];
  printf( "Mouse @ %f %f\n", event.locationInWindow.x, event.locationInWindow.y );
}

@end



@implementation YourAppDelegate

- (void) applicationDidFinishLaunching:(NSNotification *)aNotification {
  self.window.acceptsMouseMovedEvents = YES;
}
@end


如果缺少其中任何一个,它将无法工作。以上对我有用,如果仍然不起作用,其他建议是尝试致电:

[window makeMainWindow];
[window makeKeyAndOrderFront:self.window];
© www.soinside.com 2019 - 2024. All rights reserved.