2011-07-03 11 views
7

Estoy intentando implementar un esquema de URL personalizado para mi aplicación. He agregado las líneas necesarias para mi Info.plist. Después de llamar a la URL especificada (p. Ej .: myapp: //) se inicia la aplicación.Esquema de URL: Qt y mac

Si quiero manejar la URL, he encontrado estos pasos:

@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 

El código anterior funciona Si la aplicación se está ejecutando, pero si la URL es llamado y la aplicación se terminó, la evento no es atrapado Creo que esto se debe a esto: NSApplicationDidFinishLaunchingNotification. Cambiarlo a NSApplicationWillFinishLaunchingNotification hace que no se capturen eventos. Tal vez Qt lo maneje antes que yo, pero no puedo encontrar una solución al problema.

+0

Parece que escucha a la notificación NSApplicationDidBecomeActiveNotification resuelve el problema. No creo que sea la mejor manera de hacerlo, así que dejo la pregunta abierta para mejores ideas :) – birmacher

Respuesta

4

También estaba intentando hacer que mi aplicación basada en Qt manejara un esquema de URL personalizado en la Mac y seguí el mismo camino que el póster original. Resulta que Qt4 ya admite eventos de URL en Mac, y no es necesario escribir el código Objective-C para recibirlos. De hecho, este es el motivo por el que no recibió ningún evento de URL cuando configuró el controlador de eventos en respuesta a NSApplicationWillFinishLaunchingNotification: Qt registra su propio controlador después.

Cuando se desencadena una URL con su esquema personalizado, su aplicación Qt recibirá un FileOpenEvent. Tenga en cuenta que es la instancia QApplication que recibe el evento. Puede atraparlo haciendo su aplicación Qcla de subclase de aplicación o instalando un filtro de evento en la QApplication estándar. Opté por este segundo enfoque.

Aquí está el método eventFilter de mi clase de filtro de eventos personalizados, FileOpenEventFilter. Simplemente emite la señal urlOpened cuando el evento contiene una URL no vacía. También guarda la última dirección URL abierta en caso de que mi ventana principal no está completamente inicializado cuando llegue el evento (lo que ocurre en mi aplicación cuando no está ya en ejecución cuando se hace clic en la URL personalizada.)

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

Registré mi controlador en el método applicationWillFinishLaunching: de mi delegado de aplicación, y no me pierdo ningún evento. Probablemente esté inicializando su objeto EventHandler demasiado tarde para recibir esa notificación. Si desea mantenerlo como una clase separada, está bien, pero debe crear su objeto y registrarlo con NSAppleEventManager dentro del método applicationWillFinishLaunching: del delegado de su aplicación.

Cuestiones relacionadas