【问题标题】:How to make NSOpenPanel accept keyboard and mouse events in objective-c?如何让 NSOpenPanel 在 Objective-C 中接受键盘和鼠标事件?
【发布时间】:2023-03-11 02:03:01
【问题描述】:

我用 XCode 编写了 C++ 控制台应用程序,我需要打开一个文件选择器对话框。为此,我将 Cocoa 与 Objective-c 一起使用。我正在尝试打开一个 NSOpenPanel 以用于此目的。我目前正在使用以下代码:

const char* openDialog()
{
    NSOpenPanel* openDlg = [NSOpenPanel openPanel];
    [openDlg setCanChooseFiles:YES];
    [openDlg setFloatingPanel:YES];

    if ( [openDlg runModal] == NSOKButton )
    {
        for( NSURL* URL in [openDlg URLs] )
        {
            NSLog( @"%@", [URL path] );     
            return [URL.path UTF8String];
        }
    }
    
    return NULL;
}

这可行,但是创建的文件选择器不能正确接受鼠标和键盘事件。很难解释,但是例如,当我将鼠标悬停在窗口上方时从 XCode 运行代码时,鼠标的行为仍然就像在 XCode 中一样,显示插入符号。当我从终端运行应用程序时,无论何时我输入内容,它都会将输入发送到终端,即使文件选择器在“前面”。不过,单击命令会将鼠标事件正确地传递给文件选择器。

我查看了 NSOpenPanel 的文档并在 Google 上广泛搜索了这个问题,但我找不到答案。

【问题讨论】:

  • 这里有一个例子:dropbox.com/s/n2ly8qkgh7j5r93/openfile.m.zip?dl=0。如果有帮助,我会发布作为答案。问题可能是您正在使用的 main.m。演示不使用笔尖。
  • 这能回答你的问题吗? NSOpenPanel cannot get focus
  • @Willeke 不,它没有,因为这个答案是针对 Swift 的。我如何在目标 c 中做同样的事情?
  • @apodidae Dropbox 代码的哪一部分是为了解决我的问题?
  • 看看你正在使用的 main.m。我认为是这一行: NSApplication *application = [NSApplication sharedApplication];我的示例运行正常吗?

标签: c++ objective-c macos cocoa


【解决方案1】:
/*
To run in Terminal: clang openpanel.m -fobjc-arc -framework Cocoa -o openpanel && ./openpanel
*/

#import <Cocoa/Cocoa.h>

int main() {
 NSApplication *application = [NSApplication sharedApplication]; 
 [application setActivationPolicy:NSApplicationActivationPolicyAccessory];
 NSOpenPanel* openDlg = [NSOpenPanel openPanel];
 [openDlg setCanChooseFiles:YES];
 [openDlg setFloatingPanel:YES];

 if ( [openDlg runModal] == NSModalResponseOK ) {
   for( NSURL* URL in [openDlg URLs] ) {
     NSLog( @"%@", [URL path] );     
   }
 }  
 return 0;
}

感谢@Willeke。

【讨论】:

  • 是的,这行得通!谢谢!在这种情况下,应用程序意味着什么?当我从我的 C++ 应用程序运行此代码时,应用程序是指整个事物还是仅指文件选择器对话框?
  • 以下是来自 Xcode/Help/DeveloperDocumentation/NSApplication 的引用:“每个应用程序都使用单个 NSApplication 实例来控制主事件循环,跟踪应用程序的窗口和菜单,将事件分发到适当的对象(即其自身或其窗口之一),设置自动释放池,并接收应用程序级事件的通知。”它可以做很多事情。
  • 我试图编辑您的帖子,但不让我这样做。在返回之前,我们需要重新设置激活策略,以便我们的应用程序不会从 Dock 中消失。 [应用程序 setActivationPolicy:NSApplicationActivationPolicyRegular];
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多