处理Mac OS X文件打开事件BEFORE C ++ main()执行 [英] Handling Mac OS X file open event BEFORE C++ main() executes

查看:274
本文介绍了处理Mac OS X文件打开事件BEFORE C ++ main()执行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经google了很多,但仍然找不到好的解决方案:/

所以,我正在移植一个复杂的Qt5应用程序(某些网络服务的客户端)到Mac OS X(10.7。 0Lion以上)。

I've googled a lot, but still unable to find nice solution :/
So, i'm porting one complicated Qt5 application (client of some network service) to Mac OS X (10.7.0 "Lion" and higher).

我需要处理自定义文件,例如 *。xyz 自定义URL方案如 xyz://

好​​吧,Qt5有 QFileOpenEvent 处理OS X适当的事件。

:此事件仅在应用程序事件循环开始后到达(显然)!

I need to handle custom file like *.xyz and custom URL scheme like xyz://.
Okay, Qt5 has the QFileOpenEvent class to handle OS X appropriate event.
BUT: this event arrives only after the application event loop starts (obviously)!

我需要捕获和处理OS X'文件打开事件 BEFORE main 启动,因为程序逻辑设计为照顾

And i need to "catch" and handle OS X' file open event BEFORE main starts, because the program logic was designed to take care of the command line argument handling only.

简化的 main 函数代码:

int main(int argc, char[]* argv)
{
     QApplication app( argc, argv );

     QStringList arguments = app.arguments();
     if( arguments.count() == argc ) arguments.removeFirst();

     Logic appLogic( NULL, &app );
     app.installMessageHandler( &appLogic );

     // The problem:
     // **This function will always called earlier than the any event**
     if( ! appLogic.start( arguments ) ) return 0;

     // Start processing of events
     // Only after this call Logic class get the desired event
     return app.exec();
}

是否有办法获取OS X文件打开事件之前启动C ++ main 函数,或者在 argv 参数中获取my文件/ ?

也许,一些 Objective-C 黑魔法可以完成这项工作吗?

Is there a way to get an OS X' file opening event before the C++ main function starts, or to get "my" file/url in the argv parameter?
Maybe, some Objective-C black magic does the job?

start 执行许多复杂和异步的事情。事件在执行期间到达,因此当异步东西已经工作时,很难处理它。所以看起来像我只是需要防止开始执行,如果事件将到达。

NOTE: start does many complicated - and asynchronous - things. Event arrives during it's execution, so it's hard to handle it when the async stuff is already working. So looks like i just need to prevent start execution, if the event will arrive.

如果应用程序已经打开,没有问题。

If the application is already opened, there is no problem.

推荐答案

我发现了一个可行的解决方案 - 使用Qt的事件系统。 / p>

I've found one, propably weird, solution - use Qt' event system.

int main(int argc, char[]* argv)
{
    QApplication app( argc, argv );

    QStringList arguments = app.arguments();
    if( arguments.count() == argc ) arguments.removeFirst();

    Logic appLogic( NULL, &app );
    #ifdef Q_OS_MAC
    app.installMessageHandler( &appLogic );

    // Here we should alreasy get FileOpenEvent, if it occurs
    // NOTE: without this FileOpenEvent will arrive LATER
    //       than the DryRunEvent!
    app.processEvents();

    // If there is no file open event in the queue,
    // we should just open the blank program window
    // NOTE: Qt takes ownership of this event object,
    //       so you should not delete it manually
    DryRunEvent* runEv = new DryRunEvent( p );
    a.postEvent( &l, runEv, Qt::LowEventPriority );
    #endif

    ...

    #ifndef Q_OS_MAC
    if( ! appLogic.start( arguments ) ) return 0;
    #endif

    return app.exec();
}

自定义事件标题:

class BaseEvent : public QEvent
{
public:
    BaseEvent( QEvent::Type& eType ) : QEvent( getEventType( eType ) )
    {
    }

    ~BaseEvent() {}

    QEvent::Type getEventType( QEvent::Type& eType )
    {
        if( eType == QEvent::None )
        {
            eType = static_cast<QEvent::Type>( QEvent::registerEventType() );
        }
        return eType;
    }
};

class DryRunEvent : public BaseEvent
{
    QStringList m_params;

    public:
         DryRunEvent( const Parameters& params ) :
             BaseEvent( eventType ), m_params( params )
         {
         }

         ~DryRunEvent(){}

         QStringList GetCmdLineParams() const { return m_params; }

    public:
        static QEvent::Type eventType;
};

自定义事件源:

QEvent::Type ViewerDryRunEvent::eventType = QEvent::None;

逻辑类标题:

class Logic : public QObject
{
    Q_OBJECT
    Q_DISABLE_COPY( Logic )

    public:
        explicit Logic(QObject *parent, QApplication* application);
        virtual ~Logic();

    public slots:
        bool Start( QStringList parameters );
        void ReceiveParameters( QStringList parameters );
        void Stop();

        #ifdef Q_OS_MAC
        bool Logic::WasStarted() const
        {
            ... Determine wether logic was started or not ...
        }
        #endif

    private:
        #ifdef OS_MACOSX
        // Virtual overrided functions
         bool eventFilter( QObject* obj, QEvent* event )
         {
             if( event->type() == QEvent::FileOpen )
             {
                 QFileOpenEvent* fileEvent = static_cast< QFileOpenEvent* >(event);
                 Q_ASSERT( fileEvent != NULL );

                 QString uri;
                 if( fileEvent->file().isEmpty() == false )
                 {
                     uri = fileEvent->file();
                 }
                 else if( fileEvent->url().isEmpty() == false )
                 {
                     uri = fileEvent->url().toString();
                 }

                 if( uri.isEmpty() == false )
                 {
                     if( WasStarted() ) ReceiveParameters( uri );
                     else Start( uri );
                 }

                 return false;
             }
             else if( event->type() == DryRunEvent::eventType )
             {
                 DryRunEvent* myEvent = static_cast< DryRunEvent* >( event );
                 Q_ASSERT( myEvent != NULL );
                 QStringList cmdLineParams = myEvent->GetCmdLineParams();

                 Q_ASSERT( !WasStarted() );
                 if( WasStarted() ) return false;

                 if( !Start( cmdLineParams ) ) m_application->exit( 0 );
                 return false;
             }

             // Standard event processing
             return QObject::eventFilter( obj, event );
        }
        #endif
    };

我希望有人觉得这个东西很有用:)

I hope someone find this stuff useful :)

这篇关于处理Mac OS X文件打开事件BEFORE C ++ main()执行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆