簡體   English   中英

URL方案-Qt和mac

[英]URL scheme - Qt and mac

我正在嘗試為我的應用程序實現自定義 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 在我之前處理它,但我找不到解決該問題的方法。

我還試圖讓我的基於 Qt 的應用程序在 Mac 上處理自定義 URL 方案,並沿着與原始海報相同的路徑走。 原來Qt4在Mac上已經支持URL事件了,不需要再寫Objective-C代碼來接收了。 這實際上是您在設置事件處理程序以響應 NSApplicationWillFinishLaunchingNotification 時沒有收到任何 URL 事件的原因:Qt 隨后注冊了自己的處理程序。

當帶有您的自定義方案的 URL 被觸發時,您的 Qt 應用程序將收到一個 FileOpenEvent。 請注意,接收事件的是 QApplication 實例。 您可以通過使您的應用程序成為 QApplication 的子類或通過在標准 QApplication 上安裝事件過濾器來捕獲它。 我選擇了第二種方法。

這是我的自定義事件過濾器 class,FileOpenEventFilter 的 eventFilter 方法。 它只是在事件包含非空 URL 時發出信號 urlOpened。 它還保存最后打開的 URL 以防我的主要 window 在事件到達時未完全初始化(當單擊自定義 ZE6B391A8D2C4D45902A23A83B 時,我的應用程序尚未運行時會發生這種情況)。

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

我在我的應用程序委托的applicationWillFinishLaunching:方法中注冊了我的處理程序,並且我不會錯過任何事件。 您可能初始化您的EventHandler object 為時已晚,無法收到該通知。 如果您想將其作為單獨的 class 保留,那沒關系,但您應該創建 object 並在applicationWillFinishLaunching:方法中向NSAppleEventManager注冊它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM