我正在使用QtSDK 4.7.3
我在(void test())中这样做:
mgr = new QNetworkAccessManager();
reply = mgr->get(QNetworkRequest(QUrl("http://developer.qt.nokia.com/fileNotExisting.txt")));
connect(reply, SIGNAL(error(QNetworkReply::NetworkError)),
SLOT(onError(QNetworkReply::NetworkError)), Qt::ConnectionType::UniqueConnection);
当然,插槽onError被称为:
if (networkError == QNetworkReply::NetworkError::ContentNotFoundError)
{
// Messagebox starts an event loop which
// causes this slot to be called again
QMessageBox m;
m.exec();
}
如果我在onError插槽中没有messagebox / eventloop,则没有崩溃,一切正常。但是当它存在时,调用m.exec()时会再次调用onError槽。 当两个消息框都关闭并且我将函数保留为onError时,应用程序崩溃。 发生这种情况时,应用程序会尝试删除/释放内存。错误“访问冲突读取位置”没有任何帮助,调用堆栈深入到Qt dll。
我检查了什么:
信号未连接两次。
在QApplication调用它的exec函数之前和之后尝试调用test()。 (没关系)。
像HostNotFound这样的另一个错误不会两次调用onError插槽。
我的所有代码都在主线程中执行。
尝试断开onError插槽,使其仅被调用一次但仍然崩溃。
在onError()中尝试对请求进行中止。
在Qt论坛上发表了同样的问题(post)。
任何人都可以帮我弄清楚这里发生了什么吗?
以下是我用于测试的代码: main.cpp中
#include "contentnotfound.h"
#include <QtGui/QApplication>
#include <QTimer>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
ContentNotFound cnf;
// false: start test after application's event loop have started
if (true) { cnf.test(); }
else { QTimer::singleShot(2000, &cnf, SLOT(test())); }
return a.exec();
}
contentnotfound.h
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QMessageBox>
class ContentNotFound : public QObject
{
Q_OBJECT
public slots:
void test()
{
mgr = new QNetworkAccessManager();
reply = mgr->get(QNetworkRequest(QUrl("http://developer.qt.nokia.com/fileNotExisting.txt")));
connect(reply, SIGNAL(error(QNetworkReply::NetworkError)),
SLOT(onError(QNetworkReply::NetworkError)), Qt::ConnectionType::UniqueConnection);
}
private slots:
void onError(QNetworkReply::NetworkError networkError)
{
//reply->disconnect(); // Disconnect all signals
if (networkError == QNetworkReply::NetworkError::ContentNotFoundError)
{
// Messagebox starts an event loop which
// causes this slot to be called again
QMessageBox m;
m.exec();
}
}
private:
QNetworkAccessManager* mgr;
QNetworkReply* reply;
};
答案 0 :(得分:3)
Qt中有一个错误&lt; 4.8.0:https://bugreports.qt.io/browse/QTBUG-16333
修改与排队的连接解决了问题:
contentnotfound.h:
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QMessageBox>
class ContentNotFound : public QObject
{
Q_OBJECT
public slots:
void test()
{
qRegisterMetaType<QNetworkReply::NetworkError>("QNetworkReply::NetworkError");
mgr = new QNetworkAccessManager(this);
reply = mgr->get(QNetworkRequest(QUrl("http://developer.qt.nokia.com/fileNotExisting.txt")));
connect(reply, SIGNAL(error(QNetworkReply::NetworkError)),
SLOT(onError(QNetworkReply::NetworkError)), Qt::QueuedConnection);
}
private slots:
void onError(QNetworkReply::NetworkError networkError)
{
//reply->disconnect(); // Disconnect all signals
if (networkError == QNetworkReply::ContentNotFoundError)
{
// Messagebox starts an event loop which
// causes this slot to be called again
QMessageBox m;
m.exec();
}
}
private:
QNetworkAccessManager* mgr;
QNetworkReply* reply;
};