Qt:如何在共享动态C++库中使用QCoreApplication / QNetworkAccessManager

3
我正在使用Qt作为主要的IDE开发一个共享库。该库应动态链接到任何使用它的应用程序中,并且需要在Windows、OSX和Linux上使用,未来还计划支持移动平台。
Qt加载了多个非常有用的库,如QString(用于Unicode)和QNetwork。目前,我仅使用QtCore库,但发现需要在共享库中进行一些REST调用。我很快找到了几个指南,以在Qt中使用QNetworkAccessManager进行REST调用。然而,这些指南都是基于应用程序模板而不是库。显然,在我的共享库中没有控制台、GUI或主函数。
在使用QNetworkAccessManager时,QtCoreApplication总是出现在示例中。从文档中可以看到,它被描述为:
QtCoreApplication类为控制台Qt应用程序提供事件循环
我的库创建方式包含多个独立的函数,永远不需要任何控制台。执行REST调用的函数是独立的,可以在此处创建QCoreApplication和QNetworkAccessManager,然后在接收结果后删除它们。
这种方式可行吗?我尝试让它工作,但在尝试执行QtCoreApplication时程序停止了。
int argc = 1;
char appname[] = "App";
char* argv[] = {appname, NULL};
QCoreApplication app = new QCoreApplication(QAppPriv::argc, QAppPriv::argv);
app->exec();

我之前在“MakeRequest”函数中运行了以下代码,但出现了错误信息:“QEventLoop:无法在没有 QApplication 的情况下使用”:

QTimer timer;
timer.setSingleShot(true);

// Create custom temporary event loop on stack
QEventLoop eventLoop;
timer.start(5000);

// "quit()" the event-loop, when the network request "finished()"
QNetworkAccessManager mgr;
QObject::connect(&timer, SIGNAL(timeout()), &eventLoop, SLOT(quit()));
QObject::connect(&mgr, SIGNAL(finished(QNetworkReply*)), &eventLoop, SLOT(serviceRequestFinished(QNetworkReply*)));

QUrl url( QString("http://ip.jsontest.com/") );
QNetworkReply* reply = mgr.get(QNetworkRequest(url));
eventLoop.exec();

任何帮助都非常感激!!!

QCoreApplication总是指向一个内部单例对象,该对象由Qt创建一次,因此所有其他QCoreApplication对象将在内部指向它。这应该在应用程序的“main”部分中创建,其中事件循环也将运行。事件循环不仅适用于控制台应用程序,还用于将事件传播到Qt窗口对象。由于依赖于底层本机事件机制的差异,在Linux下其行为与Windows下略有不同。 - DNT
1个回答

4

您可以在库中的新线程中创建QCoreApplication的实例。您应该检查仅创建一个实例,因为每个Qt应用程序应该只包含一个QCoreApplication

class Q_DECL_EXPORT SharedLibrary :public QObject    
{
Q_OBJECT
public:
    SharedLibrary();

private slots:

    void onStarted();

private:
    static int argc = 1;
    static char * argv[] = {"SharedLibrary", NULL};
    static QCoreApplication * app = NULL;
    static QThread * thread = NULL;
};


SharedLibrary::SharedLibrary()
{
    if (thread == NULL)
    {
        thread = new QThread();
        connect(thread, SIGNAL(started()), this, SLOT(onStarted()), Qt::DirectConnection);
        thread->start();
    }
}
SharedLibrary::onStarted()
{
   if (QCoreApplication::instance() == NULL)
   {
       app = new QCoreApplication(argc, argv);
       app->exec();
   }
}  

这样你就能在非Qt应用程序中使用你的Qt共享库。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接