【问题标题】:Cocoa app with only NSSavePanel只有 NSSavePanel 的 Cocoa 应用
【发布时间】:2012-04-11 13:25:20
【问题描述】:

我正在尝试创建一个显示 SavePanel 的 Cocoa 应用程序,在用户选择文件后,它会在标准输出上打印它。我是 Objective-C 和 Cocoo 的初学者。问题是它不需要键盘输入,只能用鼠标选择文件。

这是代码:

#import <Cocoa/Cocoa.h>
#include <stdio.h>

int main(int argc, char *argv[])
{
    NSSavePanel *sPanel = [NSSavePanel savePanel];
    int result = [sPanel runModal];
    if (result == NSOKButton) {
        NSString * filename = [sPanel filename];
        char * fileStr = [filename UTF8String];
        printf("%s\n", fileStr);
    }
    return 0;
}

【问题讨论】:

  • 如果目标是学习 Cocoa,请从 Cocoa 应用程序开始。如果目标是尝试将实际 UI 与 shell 脚本集成,则可以解决问题并将 shell 功能封装在一个真实的应用程序中。我已经看到很多将 UI 与基于命令行的工作流集成的尝试,但它们普遍都很糟糕。

标签: objective-c cocoa


【解决方案1】:

AppKit/Cocoa 类需要初始化一个 NSApplication 对象以处理用户输入(除其他外)。将此行添加到 main 函数的顶部应该可以解决问题:

int main(int argc, char *argv[])
{
    [NSApplication sharedApplication]; // ** Add this **

    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    NSSavePanel *sPanel = [NSSavePanel savePanel];
    int result = [sPanel runModal];
    if (result == NSOKButton) {
        NSString * filename = [sPanel filename];
        const char * fileStr = [filename UTF8String];
        printf("%s\n", fileStr);
    }
    [pool drain];
    return 0;
}

更多信息可以在documentation for NSApplication找到,特别是以下几点:

每个应用程序必须只有一个 NSApplication 实例(或 NSApplication 的子类)。你的程序的 main() 函数应该 通过调用 sharedApplication 类方法创建此实例。
NSApplication 执行从 窗口服务器并将它们分发到适当的 NSResponder 对象。 NSApp 将事件转换为 NSEvent 对象,然后转发 NSEvent 对象到受影响的 NSWindow 对象。

按照下面 bbum 和 danielpunkass 的 cmets 的思路,这不是您真正编写 Cocoa 应用程序的方式,虽然它确实可以解决您的直接问题,但它不是一个完整或完全正确的解决方案。要扩展 Daniel 的评论并让您轻松入门,请创建一个新的 Cocoa 应用程序项目。打开应用程序委托类(为您创建),并将您的代码放在-applicationDidFinishLaunching: 方法中。正如其名称所暗示的那样,该方法在应用程序完成启动后调用,并且一切都已设置好,以便您可以正常使用 AppKit 类。随着您获得更多经验,您将更好地了解典型的 Cocoa 应用程序架构,并可以继续创建用户界面等。

【讨论】:

  • 这是在正确的轨道上,但是仅仅建立一个顶级的 NSApplication 是不够的。您需要运行应用程序的主线程运行循环才能按预期工作。无论如何,努力“使这项工作”是错误的。提问者应该从 Xcode 中一个基本的新“可可应用程序”模板开始学习,重点是用于实验的应用委托类。
  • 这似乎不是一个完整的解决方案,但它确实适用于这个简单的案例,至少在我的机器上(10.7.3)。也就是说,@bbum 和 danielpunkass 都比我更有经验和知识渊博,并且知道他们在说什么。
  • 我完全同意。对我来说,这很有趣,但实际上你永远不会在真正的应用程序中使用它。我已经修改了我的答案。
  • 但事实并非如此。键盘输入仍然集中在终端上,而不是在编辑框中。
  • @danielpunkass 说了什么(在键盘上;不像我原来的非常简洁的评论那样轻敲)。关键点在于,将 Cocoa 应用程序视为命令行编程的扩展是一种挫败感。 OP 应该从一个真正的 Cocoa 程序开始,了解它是如何工作的,然后解决他们遇到的任何问题。
猜你喜欢
  • 1970-01-01
  • 2018-06-05
  • 1970-01-01
  • 2011-10-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多