Qt:将 QCoreApplication / QNetworkAccessManager 与共享动态 C++ 库一起使用

Posted

技术标签:

【中文标题】Qt:将 QCoreApplication / QNetworkAccessManager 与共享动态 C++ 库一起使用【英文标题】:Qt: Using QCoreApplication / QNetworkAccessManager with Shared Dynamic C++ Library 【发布时间】:2014-12-30 18:00:43 【问题描述】:

我正在开发一个使用 Qt 作为主要 IDE 的共享库。该库应该为使用它的任何应用程序动态链接,并且需要用于 Windows、OSX 和 Linux 以及未来可能计划的移动平台。

Qt 加载了几个非常有用的库,例如 QString(用于 unicode)和 QNetwork。到目前为止,我只使用 QtCore 库,但发现我需要在共享库中进行一些 REST 调用。我很快找到了几个在 Qt 中使用 QNetworkAccessManager 进行 REST 调用的指南。然而,这些指南都是基于应用程序模板而不是库。显然,我的共享库中没有控制台、GUI 或主要功能。

QtCoreApplication 总是在使用 QNetworkAccessManager 的例子中。从文档中它被描述为:

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: Cannot be used without 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 对象将在内部指向它。这应该在事件循环也将运行的应用程序的“主要”部分中创建。事件循环不仅适用于控制台应用程序,还用于将事件传播到 Qt 窗口对象。与 windows 相比,它在 linux 下的行为略有不同,因为它所依赖的底层原生事件机制有所不同。 【参考方案1】:

您可以在库的新线程中创建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 共享库。

【讨论】:

以上是关于Qt:将 QCoreApplication / QNetworkAccessManager 与共享动态 C++ 库一起使用的主要内容,如果未能解决你的问题,请参考以下文章

AttributeError:“QCoreApplication”对象没有属性“setQuitOnLastWindowClosed”

多线程代码中 QSerialPort 的 Qt 错误:QCoreApplication::sendEvent:“无法将事件发送到不同线程拥有的对象

QT中的Q_OBJECT(未定义对vtable xxx的引用)[重复]

QT源码查看001-QApplication和QCoreApplication

Qt学习之系列[9] – QCoreApplication:processEvents()可能会引起递归,导致栈溢出崩溃

从Android Activity onCreate方法调用QCoreApplication方法