[英]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.