【问题标题】:Programmatically handle Cocoa events?以编程方式处理 Cocoa 事件?
【发布时间】:2018-10-10 13:10:05
【问题描述】:

我正在尝试将 cocoa 事件连接到 minimal 目标-c++ cocoa 消息代理,该代理将调用我的 c++ 函数来处理事件。

对于一个按钮,OnClick,很简单,我去:

@interface cocoa_proxy : NSObject
    - (void)action:(id)sender;
@end

@implementation cocoa_proxy
    - (void)action:(id)sender
    {
        exit(0);
    }
@end

cocoa_proxy* proxy = [[cocoa_proxy alloc] init];
[button setTarget:proxy];
[button setAction:@selector(action:)];

但是我不确定如何捕获按钮的其他事件(例如 OnPress、OnRelease、OnEnter、OnExit 等...),我似乎也无法捕获窗口或视图的事件。 任何尝试类似路线的尝试,使用格式略有不同的方法(来自网络上的各种、不完全相同但类似的问题)都会导致错误,例如:

reason: '-[NSWindow setTarget:]: unrecognized selector sent to instance xxxxx

我已经有一个想要重用的大型代码库,所以我有一个代理是至关重要的,而不仅仅是“在 Objective-C++ 中做所有事情”。

为了完整起见,这是我创建窗口的方式

window = [[[NSWindow alloc] initWithContentRect:NSMakeRect(x, y, w, h)
    styleMask:NSTitledWindowMask backing:NSBackingStoreBuffered defer:NO]
        autorelease];

需要明确的是,我不使用 XCode、Interface Builder、任何 GUI 创建软件或 Cocoa 感知软件,或使用诸如 NIB 之类的概念,一切都是按程序完成的,并且与 Objective-c++ 的交互最少。

所以我的问题是,我如何处理按钮的不同事件,以及如何以类似的方式处理 Windows 和视图的事件。

【问题讨论】:

    标签: c++ cocoa objective-c++


    【解决方案1】:

    按钮被点击时触发的动作方法(完整的按下和释放序列)并不是这样的事件。这是一系列事件的结果。

    目前尚不完全清楚您需要在什么级别进行操作,但您可能需要使用NSApplication 的自定义子类并覆盖-sendEvent:。在那里您将获得低级事件,例如鼠标左键向下、鼠标左键向上、向下键、向上键等。

    如果您只对单个窗口感兴趣,则可以改用 NSWindow 的自定义子类并在那里覆盖 -sendEvent:

    如果您不允许通过 Cocoa 以正常方式处理事件(通过在任一覆盖中调用 super),那么您应对所有应用程序对事件的响应负责。您可以依靠单击窗口控件来关闭、最小化或全屏/缩放窗口。单击 Cocoa 按钮将不起作用。等等。所以,你必须仔细选择你对这些事件做什么或不做什么。

    要获得对按钮的额外控制,您可以继承 NSButtonNSButtonCell 或两者并覆盖一堆方法。例如,您可能希望在按钮单元类中覆盖 -startTrackingAt:inView:-continueTracking:at:inView:-stopTracking:at:inView:mouseIsUp:

    【讨论】:

    • 我希望 Cocoa 像往常一样处理事件,但我也想响应这些事件。例如,当窗口调整大小时,我需要执行额外的计算。我想以一种足够通用的方式做到这一点,如果我决定我也想要 MouseMove 事件,我不必编写一个全新的界面来响应这些事件,如果你关注我的话。
    • 这些在 Cocoa 中被实现为非常不同的东西。窗口在调整大小时会发出通知(NSWindowDidResizeNotification),这与单击按钮(操作方法)不同,与低级事件(鼠标移动)不同。如果有帮助,我非常熟悉这类事情,因为我写了code to translate from Cocoa stuff to Win32(警告:LGPLv2 许可代码)。
    • 我习惯了 GTK 之类的事件消息系统或 Win32 中的消息泵样式,但是如果我将 NSWindow、NSView 和 NSButton 等子类化...,我应该能够像往常一样重载他们的事件消息,调用他们的超级用户并“处理他们”,或者还有更多的事情吗?
    • 正如我所说,某些事情(窗口大小调整)将需要观察通知或将您的对象设置为委托。但是,让我支持一下:我发现很难想象您可能拥有什么样的通用代码,它们可能对您所说的 OnPress、OnRelease、OnEnter、OnExit 等低级细节有用。这样的代码能做什么不会与 Cocoa 已经在做的事情发生冲突(突出显示按钮等)?我认为将通用代码用于“业务逻辑”而不是事件处理和 UI 操作会更有成效。
    • 代码库中没有代码不是事件处理和 UI 操作,这被抽象出来以隐藏实现细节,以便可以在任何 GUI 工具包上编写基础。子类化主要组件来处理它们的消息并不理想,但如果必须这样做,就必须这样做。
    猜你喜欢
    • 1970-01-01
    • 2014-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多