2011-10-04 4 views
5

Im en utilisant QtSDK 4.7.3QNetworkReply émet le signal d'erreur deux fois lorsque ContentNotFoundError survient lorsque la boucle d'événement est lancé dans la fente d'erreur

Je fais ceci dans (test void()):

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); 

Et Bien sûr, le onError slot est appelé:

if (networkError == QNetworkReply::NetworkError::ContentNotFoundError) 
{ 
// Messagebox starts an event loop which 
// causes this slot to be called again 
QMessageBox m; 
m.exec(); 
} 

Si je n'ai pas messagebox/eventloop dans la fente onError il n'y a pas de crash et tout fonctionne. Mais quand il est là, le slot onError est appelé à nouveau quand m.exec() est appelé. Lorsque les deux boîtes de message sont fermées et je laisse la fonction surError l'application se bloque. L'application essaie de supprimer/libérer de la mémoire lorsque cela se produit. L'erreur "Accéder à l'emplacement de lecture de violation" n'aide en rien et la pile d'appels est profonde dans les DLLs Qt. Ce que j'ai vérifié:
Le signal n'est pas connecté deux fois.
Appelé test() avant et après que QApplication appelle sa fonction exec. (n'a pas d'importance).
Une autre erreur comme HostNotFound n'appelle pas l'emplacement onError deux fois.
Tout mon code est exécuté dans le fil principal.
Essayé de déconnecter l'emplacement onError pour qu'il ne soit appelé qu'une seule fois mais qu'il se bloque toujours.
Arrêt de l'appel sur la requête dans onError().
Posté la même question sur le forum Qt (post).

Quelqu'un peut-il m'aider à comprendre ce qui se passe ici?

Voici le code que j'utilise pour le test: 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; 

}; 

Répondre

3

Il y a un bogue dans Qt 4.8.0 <: https://bugreports.qt.io/browse/QTBUG-16333

Modifier la connexion avec un en file d'attente résout le problème:

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; 

}; 
+0

Merci pour votre réponse très rapide. Cela marche. Pour clearifier, dans la solution, cette ligne est également ajoutée: qRegisterMetaType ("QNetworkReply :: NetworkError"); Une autre solution peut être trouvée dans le rapport de bogue auquel vous êtes lié mais cette solution est meilleure. Le rapport de bug dit aussi qu'avec Qt 4.8.0 ce bug sera corrigé. –

Questions connexes