2011-10-04 4 views
5

Im usando QtSDK 4.7.3QNetworkReply emette segnale di errore due volte quando ContentNotFoundError occures quando ciclo di eventi viene avviato nello slot errore

sto facendo questo in (test vuoto()):

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

E Naturalmente l'onError fessura si chiama:

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

Se non ho un MessageBox/eventloop nello slot onError non c'è incidente e tutto funziona. Ma quando è lì, lo slot onError viene richiamato quando viene chiamato m.exec(). Quando entrambe le messagebox sono chiuse e lascio la funzione onError, l'applicazione si blocca. L'applicazione tenta di cancellare/liberare memoria quando questo accade. L'errore "Accesso alla posizione di lettura delle violazioni" non è di alcun aiuto e lo stack delle chiamate si trova nelle Qt dll.

Cosa ho controllato:
Il segnale non è collegato due volte.
Provato test di chiamata() prima e dopo QApplication chiama la sua funzione exec. (non importa).
Un altro errore come HostNotFound non richiamerà lo slot onError due volte.
Tutto il mio codice è eseguito nel thread principale.
Provato a disconnettere lo slot onError in modo che venga chiamato solo una volta ma si blocca ancora.
Il tentativo di chiamata si interrompe sulla richiesta in onError().
Ho postato la stessa domanda sul forum Qt (post).

Qualcuno può aiutarmi a capire cosa sta succedendo qui?

ecco il codice che uso per il 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; 

}; 

risposta

3

C'è un bug in Qt 4.8.0 <: https://bugreports.qt.io/browse/QTBUG-16333

La modifica della connessione con una coda risolve il 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

Grazie per la risposta molto veloce. Questo funziona. Per chiarire, nella soluzione è stata aggiunta anche questa riga: qRegisterMetaType ("QNetworkReply :: NetworkError"); Un'altra soluzione può essere trovata nella segnalazione di bug a cui ti sei collegato ma questa soluzione è migliore. Il bug report dice anche che con Qt 4.8.0 questo bug verrà corretto. –