2011-07-03 31 views
7

Tôi đang cố gắng triển khai lược đồ URL tùy chỉnh cho ứng dụng của mình. Tôi đã thêm các dòng cần thiết cho Info.plist của mình. Sau khi gọi url được chỉ định (ví dụ: myapp: //) ứng dụng sẽ khởi chạy.Lược đồ URL - Qt và mac

Nếu tôi muốn xử lý URL, tôi đã tìm thấy các bước sau:

@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 

Đoạn mã trên đang làm việc nếu ứng dụng đang chạy, nhưng nếu các URL được gọi và ứng dụng đã được chấm dứt, sự kiện không bị bắt. Tôi nghĩ rằng điều này là bởi vì điều này: NSApplicationDidFinishLaunchingNotification. Thay đổi thành NSApplicationWillFinishLaunchingNotification khiến cho các sự kiện không bị bắt. Có lẽ Qt xử lý nó trước tôi, nhưng tôi không thể tìm được cách giải quyết vấn đề.

+0

Dường như nghe thông báo NSApplicationDidBecomeActiveNotification giải quyết vấn đề. Tôi không nghĩ rằng đó là cách tốt nhất để đi, vì vậy tôi để lại câu hỏi mở cho một số ý tưởng tốt hơn :) – birmacher

Trả lời

4

Tôi cũng đang cố gắng để ứng dụng dựa trên Qt của tôi xử lý lược đồ URL tùy chỉnh trên Mac và đi xuống cùng một đường dẫn như áp phích gốc. Nó chỉ ra rằng Qt4 đã hỗ trợ các sự kiện URL trên Mac, và không cần phải viết mã Objective-C để nhận chúng. Đây là lý do tại sao bạn không nhận được bất kỳ sự kiện URL nào khi bạn đặt trình xử lý sự kiện để đáp ứng với NSApplicationWillFinishLaunchingNotification: Qt đăng ký trình xử lý riêng của nó sau đó.

Khi một URL với lược đồ tùy chỉnh của bạn được kích hoạt, ứng dụng Qt của bạn sẽ nhận được một FileOpenEvent. Lưu ý rằng nó là cá thể QApplication nhận sự kiện. Bạn có thể nắm bắt nó bằng cách làm cho ứng dụng của bạn phân lớp QApplication hoặc bằng cách cài đặt một bộ lọc sự kiện trên QApplication chuẩn. Tôi đã chọn cách tiếp cận thứ hai này.

Đây là phương thức eventFilter của lớp bộ lọc sự kiện tùy chỉnh của tôi, FileOpenEventFilter. Nó chỉ phát ra url tín hiệuĐược mở khi sự kiện chứa URL không trống. Nó cũng lưu URL được mở cuối cùng trong trường hợp cửa sổ chính của tôi không được khởi tạo hoàn toàn khi sự kiện đến (điều này xảy ra trong ứng dụng của tôi khi nó chưa chạy khi URL tùy chỉnh được nhấp.)

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

Tôi đăng ký trình xử lý của mình trong phương thức applicationWillFinishLaunching: của đại biểu ứng dụng và tôi không bỏ lỡ bất kỳ sự kiện nào. Có thể bạn đang khởi tạo đối tượng EventHandler quá muộn để nhận thông báo đó. Nếu bạn muốn giữ nó như là một lớp riêng biệt, đó là ok, nhưng bạn nên tạo đối tượng của bạn và đăng ký nó với NSAppleEventManager trong phương thức applicationWillFinishLaunching: của đại biểu ứng dụng của bạn.

Các vấn đề liên quan