从c ++应用程序打开cocoa模式窗口

时间:2018-05-25 12:17:59

标签: c++ objective-c macos

我需要从插件级别从C ++应用程序打开macOS上的模式对话框 - 无法访问任何现有的窗口,句柄等(应用程序是用QT编写的)。所以基本上我有一个处理程序,我需要构建窗口并显示它,然后在关闭对话框后继续。

我该怎么办?

我在Xcode中创建了xib / nib(Window.nib)文件,将其包含在我的插件包的Res​​ources文件夹中,然后调用它(在* .mm文件中编译):

NSWindowController * windowController = 
    [[NSWindowController alloc] initWithWindowNibName:@"Window"];
[[NSApplication sharedApplication] runModalForWindow: 
    windowController.window];

但看起来第二行失败了。也许我没有在UI线程中运行它?还有什么指示我还能尝试什么?

1 个答案:

答案 0 :(得分:0)

首先尝试在这样的代码中创建一个新窗口:How do I create a Cocoa window programmatically?

并将所有代码包装在主线程中运行。

这对我有用:

MyDialog(NSWindowController)

@interface MyDialog : NSWindowController
- (instancetype)initWithFrame:(NSRect)frame;
- (void)runModal;
@end

@implementation MyDialog

- (instancetype)initWithFrame:(NSRect)frame {
    NSWindowStyleMask windowMask = NSWindowStyleMaskTitled
        | NSWindowStyleMaskClosable | NSWindowStyleMaskResizable;
    NSWindow *window = [[NSWindow alloc] initWithContentRect:frame
                                                   styleMask:windowMask
                                                     backing:NSBackingStoreBuffered
                                                       defer:NO];

    [NSNotificationCenter.defaultCenter addObserver:self
                                           selector:@selector(windowWillClose:)
                                               name:NSWindowWillCloseNotification
                                             object:nil];
    return [super initWithWindow:window];
}

- (void)dealloc {
    [NSNotificationCenter.defaultCenter removeObserver:self];
}

- (void)runModal {
    [[NSApplication sharedApplication] runModalForWindow:self.window];
}

- (void)windowWillClose:(NSNotification *)notification {
    [[NSApplication sharedApplication] stopModal];
}

@end

内部呈现功能:

[NSOperationQueue.mainQueue addOperationWithBlock:^{
    NSRect frame = NSMakeRect(0, 0, 200, 200);
    MyDialog *dialog = [[MyDialog alloc] initWithFrame:frame];
    [dialog runModal];
    NSLog(@"done");
}];

如果可行,您可以在Window.xib的帮助下获得相同的结果,但是您需要确保存在相应的Window.nib文件(已编译的xib),并且可以找到它在运行时从你的插件。如果您将此文件放在插件资源中的某个位置,则可以使用initWithWindowNibPath:指定它的完整路径。