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()可能会引起递归,导致栈溢出崩溃