【问题标题】:Access main window from a NSDocument class从 NSDocument 类访问主窗口
【发布时间】:2012-01-08 15:38:03
【问题描述】:

我有一个 NSDocument 类,我需要在其中访问主菜单窗口,即在应用启动时打开的那个。当我从应用程序在该窗口中操作时,一切似乎都可以工作,但是当尝试从readFromFileWrapper:ofType:error: 执行相同的操作时,我访问的窗口似乎为零。为什么会这样?

编辑:处理这个的一些代码:

- (BOOL)readFromFileWrapper:(NSFileWrapper *)fileWrapper ofType:(NSString *)typeName error:(NSError **)outError
{
    if([[NSFileManager alloc] fileExistsAtPath:[NSString stringWithFormat:@"%@/Project.plist",[[self fileURL] path]]]) {
        NSLog(@"%@", [[self fileURL] path]);

        NSDictionary *project = [NSDictionary dictionaryWithContentsOfFile:[NSString stringWithFormat:@"%@/Project.plist",[[self fileURL] path]]];

        if([[project objectForKey:@"type"] isEqualToString:@"vote"]) {

            [self openProject:[[self fileURL] path] type:@"vote"];

            return YES;

        } else if([[project objectForKey:@"type"] isEqualToString:@"quiz"]) {

            [self openProject:[[self fileURL] path] type:@"quiz"];

            return YES; 

        } else {
            return NO;
        }
    } else {
        return NO;
    }
}

那是我的readFromFileWrapper:ofType:error: 方法。这是我的openProject:type: 方法:

-(void)openProject:(NSString *)filepath type:(NSString *)type 
{
    NSLog(@"Opening project @ %@",filepath);
    NSLog(@"%@", [MainWindow description]);
    [projectDesignerView setFrame:[[[[MainWindow contentView] subviews] objectAtIndex:0] frame]];
    [projectDesignerToolbar setFrame:[MainWindow frame] display:FALSE];
    [[MainWindow contentView] replaceSubview:[[[MainWindow contentView] subviews]objectAtIndex:0] with:projectDesignerView];
    [[projectDesignerToolbar toolbar] setShowsBaselineSeparator:YES];
    [MainWindow setToolbar:[projectDesignerToolbar toolbar]];
    [MainWindow setRepresentedFilename:filepath];
    [MainWindow setTitle:[NSString stringWithFormat:@"%@ - %@", [[filepath lastPathComponent] stringByDeletingPathExtension], [projectDesignerToolbar title]]];
    NSString *path = [[NSBundle mainBundle] pathForResource:@"projectDesigner" ofType:@"html"];
    NSURL *url = [NSURL fileURLWithPath:path];
    [[projectDesignerWebview mainFrame] loadRequest:[NSURLRequest requestWithURL:url]];
}

NSLog(@"%@", [MainWindow description]); 返回 nil,此时 MainWindow 应该是主应用程序窗口。我认为问题在于双击文件会重新分配所有文件,因此失败了。

【问题讨论】:

  • 请发布您的代码,以便我们能够准确了解您在做什么,但它不能正常工作。
  • 问题是我不知道要准确发布什么代码。我试试
  • 我刚刚发布的代码有什么线索吗?
  • 你在哪里初始化/设置MainWindow?此外,MainWindow 可能应该称为mainWindow。将变量名大写是不好的风格。类名(例如 NSString)通常大写。当您将变量名大写时,它会使您的代码难以阅读和遵循,因为它使它们看起来像类名。
  • MainWindow 是一个连接到 MainMenu.xib 中的 Window 的插座。关于命名,是的,我认为这样称呼会更好,但是写的很匆忙,没有时间更改它:)

标签: macos cocoa nswindow nsdocument


【解决方案1】:

您的要求并不完全清楚。您提到MainWindow 是MainMenu.xib 中的一个插座,但您没有指定定义插座的类。

如果此窗口设计为具有单个主“项目”窗口,则应在应用程序委托中分配 outlet 属性。

然后您可以使用 [(YourAppDelegate*)[NSApp delegate] mainWindow]; 之类的东西从其他类访问它。

但是,如果您尝试获取对当前文档窗口的引用,那么它会稍微复杂一些。

NSDocument 默认没有window 出口的原因是它被设计为与NSWindowController 的实例一起工作,这些实例本身管理与文档相关的各种窗口。这样一个文档可以有多个窗口显示相同数据的不同视图、与文档相关的附加调色板等。 NSWindowController 的每个实例都有自己的窗口 nib 文件和 window 出口。

默认情况下,如果您没有专门创建 NSWindowController 实例并将其分配给文档,NSDocument 会为您创建一个 NSWindowController 实例。这是自动的,你甚至不需要知道窗口控制器的存在。

这意味着,如果您自己不使用 NSWindowController 实例管理文档窗口,则可以将窗口附加到由 NSDocument 自动创建的 NSWindowController,如下所示:

/* Only implement this in an NSDocument instance where the 
   automatic window controller is being used.
   If the document has multiple window controllers, you must
   keep track of the main window controller yourself
   and return its window
*/
- (NSWindow*)documentWindow
{
    if([[self windowControllers] count] == 1)
    {
        return [[[self windowControllers] firstObject] window]; 
    }
    return nil;
}

【讨论】:

    【解决方案2】:

    处理这个问题的正常方法是向您的 NSDocument 子类添加一个 IBOutlet,然后将其连接到 .xib 文件中的文档窗口。

    在您的 .h 中:

    @interface MyDocument : NSDocument
    
    @property (nonatomic, assign) IBOutlet NSWindow *docWindow;
    
    @end
    

    在你的 .m 中:

    @implementation MyDocument : NSDocument
    
    @synthesize docWindow;
    
    @end
    

    然后,最重要的部分,打开 MyDocument.xib(或其他任何名称),然后将连接从 File's Owner(假设这是您的 NSDocument 子类,默认情况下)拖到主文档窗口,然后挂钩它到 docWindow 出口。

    【讨论】:

    • 如果你真的这样做了但它不起作用,恐怕我不能在没有看到更多代码和/或 .xib 文件的情况下说出问题所在。跨度>
    猜你喜欢
    • 2019-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-31
    • 1970-01-01
    • 2019-11-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多