从 NSDocument 类访问主窗口

发布于 2024-12-25 10:51:24 字数 2335 浏览 1 评论 0原文

我有一个 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 应该时是主应用程序窗口。我认为问题在于双击文件会重新分配所有文件,因此会失败。

I have a NSDocument class, where I'd need to access the main menu window, the one that gets opened when the app start. When I operate in that window from the app all seems to work, but when trying to do the same operations from readFromFileWrapper:ofType:error: the window I access seems to be nil. Why this happens?

EDIT: Some code which deals with this:

- (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;
    }
}

That is my readFromFileWrapper:ofType:error: method. Here is my openProject:type: method:

-(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]); returns nil, when MainWindow should be the Main App Window. I think the problem is that double-clicking on a file reallocs all, and hence is failing.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

明月夜 2025-01-01 10:51:25

处理此问题的正常方法是将 IBOutlet 添加到 NSDocument 子类中,然后将其连接到 .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 出口。

The normal way to handle this is to add an IBOutlet to your NSDocument subclass, then hook it up to the document window in the .xib file.

In your .h:

@interface MyDocument : NSDocument

@property (nonatomic, assign) IBOutlet NSWindow *docWindow;

@end

In your .m:

@implementation MyDocument : NSDocument

@synthesize docWindow;

@end

Then, the most important part, open up MyDocument.xib (or whatever it's called), and drag a connection from File's Owner (assuming that's your NSDocument subclass, which it is by default) to the main document window, and hook it up to the docWindow outlet.

梦回梦里 2025-01-01 10:51:24

目前还不完全清楚你在问什么。您提到 MainWindowMainMenu.xib 中的一个插座,但您没有指定哪个类定义该插座。

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

然后,您可以使用诸如 [(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;
}

It's not entirely clear what you're asking. You mention that MainWindow is an outlet in MainMenu.xib but you don't specify what class is defining the outlet.

If this window is designed to have a single main "project" window then you should assign the outlet property in your application delegate.

You can then access this from other classes using something like [(YourAppDelegate*)[NSApp delegate] mainWindow];.

If, however, you are trying to obtain a reference to the window of the current document then it's a little bit more complicated.

The reason that NSDocument does not have a window outlet by default is that it is designed to work with instances of NSWindowController that themselves manage the various windows related to the document. This is so a document can have multiple windows showing different views of the same data, additional palettes related to the document and so on. Each instance of NSWindowController would have its own window nib file and window outlet.

By default, NSDocument creates a single instance of NSWindowController for you if you do not specifically create and assign NSWindowController instances to the document. This is automatic, you don't need to even know the window controller exists.

That means that if you aren't managing your document windows with NSWindowController instances yourself, you can get the window attached to the NSWindowController that is automatically-created by NSDocument like so:

/* 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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文