【问题标题】:URL scheme - Qt and macURL 方案 - Qt 和 mac
【发布时间】:2011-09-27 13:07:59
【问题描述】:

我正在尝试为我的应用程序实现自定义 URL 方案。我已经为我的 Info.plist 添加了必要的行。调用指定的 url(例如:myapp://)后,应用程序启动。

如果我想处理 URL,我找到了以下步骤:

@interface EventHandler : NSObject {
}
@end

@implementation EventHandler
- (id)init {
    self = [super init];

    if (self) {
        NSLog(@"eventHandler::init");

        NSNotificationCenter* defaultCenter = [NSNotificationCenter defaultCenter];
        [defaultCenter addObserver:self
                        selector:@selector(applicationDidFinishLaunching:)
//                        name:NSApplicationWillFinishLaunchingNotification
          name:NSApplicationDidFinishLaunchingNotification
                        object:nil];
    }
    return self;
}

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    NSAppleEventManager *appleEventManager = [NSAppleEventManager sharedAppleEventManager];
    [appleEventManager setEventHandler:self andSelector:@selector(handleGetURLEvent:withReplyEvent:) forEventClass:kInternetEventClass andEventID:kAEGetURL];
}

- (void)handleGetURLEvent:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent
{
    NSString* url = [[event paramDescriptorForKeyword:keyDirectObject] stringValue];
    NSLog(@"%@", url);
}

@end

如果应用程序正在运行,则上面的代码可以工作,但如果 URL 被调用并且应用程序被终止,则不会捕获事件。我认为这是因为:NSApplicationDidFinishLaunchingNotification。 将其更改为 NSApplicationWillFinishLaunchingNotification 会导致捕获非事件。也许 Qt 在我之前处理了它,但我找不到解决该问题的方法。

【问题讨论】:

  • 听 NSApplicationDidBecomeActiveNotification 通知似乎可以解决问题。我认为这不是最好的方法,所以我将这个问题留给一些更好的想法:)

标签: cocoa qt macos url


【解决方案1】:

我还试图让我的基于 Qt 的应用程序在 Mac 上处理自定义 URL 方案,并沿着与原始海报相同的路径。事实证明,Qt4 在 Mac 上已经支持 URL 事件,不需要编写 Objective-C 代码来接收它们。这实际上是您设置事件处理程序以响应 NSApplicationWillFinishLaunchingNotification 时没有收到任何 URL 事件的原因:Qt 之后注册了自己的处理程序。

当触发带有您的自定义方案的 URL 时,您的 Qt 应用程序将收到一个 FileOpenEvent。请注意,接收事件的是 QApplication 实例。您可以通过使您的应用程序成为 QApplication 的子类或通过在标准 QApplication 上安装事件过滤器来捕获它。我选择了第二种方法。

这是我的自定义事件过滤器类 FileOpenEventFilter 的 eventFilter 方法。它只是在事件包含非空 URL 时发出信号 urlOpened。它还会保存上次打开的 URL,以防我的主窗口在事件到达时未完全初始化(当单击自定义 URL 时,我的应用程序尚未运行时会发生这种情况。)

bool FileOpenEventFilter::eventFilter(QObject* obj, QEvent* event)
{
    if (event->type() == QEvent::FileOpen)
    {
        QFileOpenEvent* fileEvent = static_cast<QFileOpenEvent*>(event);
        if (!fileEvent->url().isEmpty())
        {
            m_lastUrl = fileEvent->url().toString();
            emit urlOpened(m_lastUrl);
        }
        else if (!fileEvent->file().isEmpty())
        {
            emit fileOpened(fileEvent->file());
        }

        return false;
    }
    else
    {
        // standard event processing
        return QObject::eventFilter(obj, event);
    }
}

【讨论】:

    【解决方案2】:

    我在我的应用程序委托的applicationWillFinishLaunching: 方法中注册了我的处理程序,并且我不会错过任何事件。您可能初始化您的 EventHandler 对象为时已晚,无法收到该通知。如果你想把它作为一个单独的类,那没关系,但你应该创建你的对象并在你的应用程序委托的applicationWillFinishLaunching: 方法中使用NSAppleEventManager 注册它。

    【讨论】:

      猜你喜欢
      • 2013-11-05
      • 2015-06-19
      • 1970-01-01
      • 2013-05-11
      • 1970-01-01
      • 1970-01-01
      • 2011-01-15
      • 2010-12-20
      • 1970-01-01
      相关资源
      最近更新 更多