Cocoa:插件无法打开应用程序窗口

发布于 2024-08-24 05:45:47 字数 1001 浏览 4 评论 0原文

我正在为 OsiriX 开发一个插件。

在该应用程序中我有 3-4 个 nib 文件。另外,在插件中,还有名为 PluginFilter 的文件(.h 和 .m),其中存在名为 - (long) filterImage:(NSString) menuName 的方法,插件从该文件开始执行。现在我的问题是,我已经返回启动主窗口的代码位于其他一些 .m 文件中,我必须使用上面提到的方法调用该文件。

该应用程序有多个 nib 文件。我有一个名为 PluginFilter 的插件,调用者为:

- (long) filterImage:(NSString*) menuName

以此方法调用时,插件应打开一个窗口。定义窗口控制器的代码位于另一个笔尖中。当我在插件中调用 filterimage 方法时,该窗口永远不会出现。

这是我的 filterImage: 方法。

#import "XGridInOsiriXFilter.h"
#import "MainWindowController.h"

@implementation XGridInOsiriXFilter

- (void) initPlugin
{

}

- (long) filterImage:(NSString*) menuName
{

    MainWindowController *mainWindowController = [[GridSampleMainWindowController alloc] init];
    [mainWindowController showWindow:self ];
    [mainWindowController release];

    return 0;
}

@end

调用该方法不会产生警告或错误,窗口根本不会出现。

I am developing an plugin for OsiriX.

In that app i have 3-4 nib files. Also in for plugin there are files (.h & .m) called PluginFilter where method called - (long) filterImage:(NSString) menuName is present from which the plugin start execution. Now my problem is that, I have return the code to launch main window is in some other .m file and I have to call that file using the method mentioned above.

The app has multiple nib files. I have a plugin name PluginFilter called by:

- (long) filterImage:(NSString*) menuName

The plugin should open a window when called by this method. The code that defines the window controller is in another nib. When I call the filterimage method in the plugin, the window never appears.

Here is my filterImage: method.

#import "XGridInOsiriXFilter.h"
#import "MainWindowController.h"

@implementation XGridInOsiriXFilter

- (void) initPlugin
{

}

- (long) filterImage:(NSString*) menuName
{

    MainWindowController *mainWindowController = [[GridSampleMainWindowController alloc] init];
    [mainWindowController showWindow:self ];
    [mainWindowController release];

    return 0;
}

@end

Calling the method produces not warnings or errors, the window simply fails to appear.

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

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

发布评论

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

评论(2

阳光下慵懒的猫 2024-08-31 05:45:47

我意识到这可能来得太晚了,但我一直在寻找一种方法来完成您所要求的同样的事情并找到了它。您可以使用 NSBundle 加载所需的笔尖并将其指向实例化的控制器。喜欢:

@implementation YourPluginFilter

- (void) initPlugin
{
yourWindowController = [[YourWindowController alloc] init];
NSLog(@"Initialized YourWindowController");
}

- (long) filterImage:(NSString*) menuName
{
if (yourWindowController && [NSBundle loadNibNamed:@"YourNibName" owner:yourWindowController]) {
        NSLog(@"Activated yourWindowController");
    return 0;
} else {
    return -1;
}
}

@end

I recognize this may be coming a little too late but I was looking for a way to do the same thing you are asking for and found it. You can use NSBundle to load the desired nib and point it to an instantiated controller. Like:

@implementation YourPluginFilter

- (void) initPlugin
{
yourWindowController = [[YourWindowController alloc] init];
NSLog(@"Initialized YourWindowController");
}

- (long) filterImage:(NSString*) menuName
{
if (yourWindowController && [NSBundle loadNibNamed:@"YourNibName" owner:yourWindowController]) {
        NSLog(@"Activated yourWindowController");
    return 0;
} else {
    return -1;
}
}

@end
自由范儿 2024-08-31 05:45:47

您通常不会从插件打开应用程序的主窗口。根据定义,插件并不总是存在,因此您不应将关键代码放入其中。您也不希望多个插件打开同一个逻辑窗口。

相反,主窗口应正常由应用程序委托显示,但窗口的内容可以由插件处理(如果插件可用)。

主应用程序应加载并配置主窗口,并且仅调用插件来处理窗口的内容。

即便如此,从技术上来说,从插件打开窗口是可能的,因此(1)插件未加载且方法未调用(插入断点/日志进行确认)或(2)窗口控制器配置错误,因此它不打开窗户。在插件外部测试控制器以确认其工作正常。更好的是,将窗口打开代码移到插件之外。

Edit01:

来自评论:

我对上面的内容做了一些修改
代码如下

- (long) filterImage:(NSString*) menuName { 
    MainWindowController *mainWindowController = [[GridSampleMainWindowController alloc] init:self];            
    [mainWindowController showWindow:self ]; 
    [mainWindowController release]; 
    return 0; 
}

但它表明没有
找到 -init 方法。为什么会这样显示,因为 -init 方法是 der
在MainWindowController.m文件中

那么,这里有两个问题。

(1) 将 mainWindowController 定义为类 MainWindowController,但使用类 GridSampleMainWindowController 对其进行初始化。如果 MainWindowControllerGridSampleMainWindowController 的子类,这将起作用,但会生成警告。您应该像

GridSampleMainWindowController *mainWindowController = [[GridSampleMainWindowController alloc] init:self];  

MainWindowController *mainWindowController = [[MainWindowController alloc] init:self]; 

(2) 那样初始化它,或者 (2) 释放控制器,而没有任何其他对象保留它,这会杀死它。当窗口控制器死亡时,它会释放它控制的窗口。这很可能就是您什么也看不到的原因。

您应该弄清楚您希望控制器成为哪个类,然后将其设置为插件类的保留属性,以便可以将其保留在其窗口中。

它抱怨哪个 init 方法?您的 initPlugin 不执行任何操作并返回 void 如果这是插件的实际初始化方法,则该插件将永远不会加载。它至少应该是这样的:

- (id) initPlugin
{
    self=[super init];
    return self;
}

看起来您来自纯 C 背景,这非常适合这个环境,但您需要了解 Objective-C 语言的面向对象部分。您仍在编写方法,就好像它们是老式 C 函数一样,并且存在重要且通常是微妙的差异。

抱歉我昨天错过了这一切。我看到了“插件”并关注了问题的错误方面。

编辑02:

不,我不是在谈论我的 initPlugin
方法。我正在谈论我的初始化
方法里面有
MainWindowController.m文件

- (id)init { 
      self = [super initWithWindowNibName:@"MainWindow"]; 
      return self; 
}

这将返回 MainWindowController 超类的实例。如果您不进行任何自定义,则无需重写子类中的 init 方法。只需使用继承的版本即可:

MainWindowController *mainWindowController = [[MainWindowController alloc] initWithWindowNibName:@"MainWindow"]; 

You would normally not open the app's main window from a plugin. Plugins by definition my not always be present so you should not put critical code in them. Neither would you want multiple plugins opening the same logical window.

Instead, the main window should be displayed by the app delegate as normal but the content of the window can be processed by a plugin if the plugin is available.

The main application should load and configure the main window and only call the plugin to process the contents of the window.

Even so it is technically possible to open a window from a plugin so either (1) the plugin is not being loaded and the method is not being called (insert breakpoint/log to confirm) or (2) the window controller is misconfigured so that it does not open the window. Test the controller outside the plugin to confirm it works. Better yet, move the window opening code outside the plugin.

Edit01:

From comment:

I have made some changes in the above
code as follows

- (long) filterImage:(NSString*) menuName { 
    MainWindowController *mainWindowController = [[GridSampleMainWindowController alloc] init:self];            
    [mainWindowController showWindow:self ]; 
    [mainWindowController release]; 
    return 0; 
}

but it is showing wanring that no
-init method found. Why it is showing like this because -init method is der
in the MainWindowController.m file

Well, you have two problems here.

(1) You set define mainWindowController as of class MainWindowController but you initialize it with class GridSampleMainWindowController. If MainWindowController is a subclass of GridSampleMainWindowController this will work but will generate warnings. You should instead initialize it like

GridSampleMainWindowController *mainWindowController = [[GridSampleMainWindowController alloc] init:self];  

or

MainWindowController *mainWindowController = [[MainWindowController alloc] init:self]; 

(2) You release the controller without any other object retaining it which will kill it. When a window controller dies it deallocates the windows it controls. This is most likely why you see nothing.

You should sort out what class you want the controller to be and then set it as a retained property of the plugin class so you can keep it an its window around.

Which init method is it complaining about? Your initPlugin does nothing and returns a void if that is the plugin's actual initialization method then the plugin will never load. It should at least look like this:

- (id) initPlugin
{
    self=[super init];
    return self;
}

It looks like you come from a pure C background which is great for this environment but you need to learn about the object oriented parts of the Objective-C language. You're still writing methods as if they were old school C functions and there are important and oft times subtle differences.

Sorry I missed all this yesterday. I saw "plugin" and focused on the wrong aspect of the problem.

Edit02:

No i m not talking about my initPlugin
method. I am talking about my init
method which is there in
MainWindowController.m file

- (id)init { 
      self = [super initWithWindowNibName:@"MainWindow"]; 
      return self; 
}

This will return an instance of the MainWindowController's super class. If you're not doing any customization you have no need to override the init method in you subclass. Just use the inherited version thusly:

MainWindowController *mainWindowController = [[MainWindowController alloc] initWithWindowNibName:@"MainWindow"]; 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文