我的一个客户有一个组织,我正在开发基于Qt的客户端 – 服务器的东西与很多有趣的小部件和套接字。
公司内部的另一个组织希望使用基于QTcpSocket的客户端数据提供程序类的封装版本。 (基本上是什么听起来像,从服务器提供数据到客户端显示)
但是,该组织主要使用MFC来构建一个巨大的应用程序,而且不久以后就不会有任何改变。基于Qt的DLL也是延迟加载,以便在某些配置中可以部署该功能。
我已经开始工作了,但这有点麻烦。这是我现在的解决方案:
DLL包装器类构造函数调用QCoreApplication :: instance()来查看它是否为NULL。如果它为NULL,它假定它在一个非Qt应用程序中,并创建一个自己的QCoreApplication实例:
if (QCoreApplication::instance() == NULL) { int argc = 1; char* argv[] = { "dummy.exe",NULL }; d->_app = new QCoreApplication(argc,argv); // safe? } else d->_app = NULL;
然后它将设置一个Windows计时器偶尔调用processEvents():
if (eventTimerInterval > 0) { // STATE: start a timer to occasionally process the Qt events in the event queue SetTimer(NULL,(UINT_PTR)this,eventTimerInterval,CDatabaseLayer_TimerCallback); }
回调简单地使用timerID作为指向类实例的指针调用processEvents()函数。 SetTimer()文档说HWND为NULL时,它会忽略timerID,因此这似乎是完全有效的。
VOID CALLBACK BLAHBLAH_TimerCallback(HWND hwnd,UINT uMsg,UINT_PTR idEvent,DWORD dwTime) { ((BLAHBLAH*)idEvent)->processEvents(); // basically just calls d->_app->processEvents(); }
然后我将摧毁QCoreApplication实例作为析构函数中的最后一件事。
BLAHBLAH::~BLAHBLAH() { .. other stuff QCoreApplication* app = d->_app; d->_app = NULL; delete d; if (app != NULL) delete app; }
如果主机应用程序希望对processEvents()本身进行调用,则可以在eventTimerInterval中传递0,并调用BLAHBLAH :: processEvents()本身。
有什么想法吗?将该应用移植到Qt是不可选的。这不是我们的
它似乎工作,但可能有几个假设在这里被打破。我可以用这样的虚拟参数构造QCoreApplication吗?事件队列是否能够以这种方式运行?
我不想让我以后再吹起来。思考?
我有一个全局命名空间:
// Private Qt application namespace QAppPriv { static int argc = 1; static char * argv[] = {"sharedlib.app",NULL}; static QCoreApplication * pApp = NULL; static QThread * pThread = NULL; };
我在一个QObject(这是moc’ed)中有一个OpenApp方法,如下所示:
// Initialize the app if (QAppPriv::pThread == NULL) { // Separate thread for application thread QAppPriv::pThread = new QThread(); // Direct connection is mandatory connect(QAppPriv::pThread,SIGNAL(started()),this,SLOT(OnExec()),Qt::DirectConnection); QAppPriv::pThread->start(); }
这里是OnExec插槽:
if (QCoreApplication::instance() == NULL) { QAppPriv::pApp = new QCoreApplication(QAppPriv::argc,QAppPriv::argv); QAppPriv::pApp->exec(); if (QAppPriv::pApp) delete QAppPriv::pApp; }
到目前为止,它似乎工作正常,我不知道如果我需要删除的应用程序在最后,如果我找到一些东西,我会更新我的答案。