2011-10-04 8 views
5

Im usando QtSDK 4.7.3QNetworkReply emite señal de error dos veces cuando ContentNotFoundError occures cuando se inicia ciclo de eventos en la ranura de error

que estoy haciendo esto en (test de vacío()):

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

Y de por supuesto, el onError ranura se llama:

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

Si no tengo un cuadro de mensaje/eventloop en la ranura onError no hay ningún accidente y todo funciona. Pero cuando está allí, entonces se llama nuevamente a la ranura onError cuando se llama a m.exec(). Cuando ambos messageboxes están cerrados y dejo la función en Error, la aplicación falla. La aplicación intenta eliminar/liberar memoria cuando sucede esto. El error "Acceso a la ubicación de lectura de violación" no ayuda a ninguno y la pila de llamadas se encuentra en profundidad en Qt dlls.

Lo que he comprobado:
La señal no está conectada dos veces.
Prueba de llamada probada() antes y después de que QApplication llame a su función ejecutiva. (no importa).
Otro error como HostNotFound no llamará a la ranura onError dos veces.
Todo mi código se ejecuta en el hilo principal.
Intentó desconectar la ranura onError, por lo que solo se invoca una vez pero aún así falla.
Intento de llamada abortar en la solicitud en onError().
Publicada la misma pregunta en el foro de Qt (post).

¿Alguien me puede ayudar a descubrir qué está pasando aquí?

Este es el código que utilizo para la prueba: 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; 

}; 

Respuesta

3

Hay un error en Qt 4.8.0 <: https://bugreports.qt.io/browse/QTBUG-16333

La modificación de la conexión con una en cola resuelve el problema:

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

Gracias por su pronta respuesta. Esto funciona. Para borrar, en la solución esta línea también se agrega: qRegisterMetaType ("QNetworkReply :: NetworkError"); Se puede encontrar otra solución en el informe de errores al que se ha vinculado, pero esta solución es mejor. El informe de error también dice que con Qt 4.8.0 este error será reparado. –

Cuestiones relacionadas