2011-07-03 3 views
7

내 응용 프로그램에 대한 사용자 지정 URL 스키마를 구현하려고합니다. 내 Info.plist에 필요한 라인을 추가했다. 지정된 URL (예 : myapp : //)을 호출하면 응용 프로그램이 시작됩니다. URL 체계 - Qt 및 mac

나는 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가 나보다 먼저 처리하지만, 문제의 해결 방법을 찾을 수 없습니다.

+0

그것은 그 청취 보인다 NSApplicationDidBecomeActiveNotification 알림은 문제를 해결합니다. 나는 그것이가는 것이 가장 좋은 방법이라고 생각하지 않는다. 그래서 나는 더 좋은 아이디어를 위해 열린 질문을 남겨두고있다. :) – birmacher

답변

4

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

내 응용 프로그램 대리인의 applicationWillFinishLaunching: 메서드에 내 처리기를 등록하고 어떤 이벤트도 놓치지 않습니다. EventHandler 개체를 너무 늦게 초기화하여 알림을받을 수 없습니다. 별도의 클래스로 유지하려면 괜찮습니다. 그러나 응용 프로그램 대리자의 메서드 내에서 개체를 만들고 NSAppleEventManager에 등록해야합니다.