Problems with QNetworkRequest, it does not send signals.
Hello, I have a problem with my program, I hope you could help me!
I have written this code for download a file from internet. The problem is that it does not get download the file. I think that's code
Code:
reply = qnam.get(QNetworkRequest(url));
does not emit the signal ReadyRead, such as say the oficial documentation.
Code:
Posts a request to obtain the contents of the target request and returns a new QNetworkReply object opened for reading which emits the readyRead() signal whenever new data arrives.
Which is the problem of the code?
updates.h
Code:
#include <QString>
#include <QFile>
#include <QNetworkReply>
#include <QtNetwork/QtNetwork>
#include <QtNetwork/QNetworkAccessManager>
#include <QWidget>
#include <QObject>
#include <QMainWindow>
#include <QProgressDialog>
{
Q_OBJECT
public:
void checkUpdates
(QString version
);
private:
QString fileNameUpdate,versionInstalled,pathDownload;
QNetworkReply *reply;
QNetworkAccessManager qnam;
bool httpRequestAborted;
int iVersion;
private slots:
void httpFinished();
void httpFinishedDownload();
void httpReadyRead();
void replyErrorActualizaciones(QNetworkReply::NetworkError code);
void updateDataReadProgress(qint64,qint64);
};
updates.cpp
Code:
#include <QUrl>
#include <QFileInfo>
//#include <QObject>
#include <QDebug>
#include <QMessageBox>
#include <QFileDialog>
#include <QProcess>
#include <QStringList>
#include "updates.h"
updates
::updates (QWidget *parent
) :{
iVersion =0;
}
void updates
::checkUpdates(QString version
) {
httpRequestAborted=false;
//Variables
QUrl url
("http://weblink.link/link");
QFileInfo fileInfo
(url.
path());
//url.path() devuelve a partir del .es/ .com/ .org/ fileNameUpdate.append(fileInfo.fileName());//nombre del arvhivo //.fileinfo -Returns the name of the file, excluding the path.
file = new QFile(fileNameUpdate
);
//Hasta aqui simplemente creo el archivo para poder escribir en el
versionInstalled = version;
reply = qnam.get(QNetworkRequest(url));//se supone que esto emite la readyRead(), pero no funciona!!
qDebug() << reply;
connect(reply, SIGNAL(finished()),this, SLOT(httpFinished()));
connect(reply, SIGNAL(readyRead()),this, SLOT(httpReadyRead()));
connect(reply,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(replyErrorActualizaciones(QNetworkReply::NetworkError)));
}//checkUpdate
//Private slots
void updates::httpFinished()
{
//Variables
bool ok;
double versionServidor;
if (httpRequestAborted)
{
if (file)
{
file->close();
file->remove();
delete file;
file = 0;
}
reply->deleteLater();
return;
}//if
file->close();
.
.
.
.
.
void updates::httpReadyRead()
{
if (file)
file->write(reply->readAll());
qDebug() << "Ready";
}//httpReadyRead
void updates::replyErrorActualizaciones(QNetworkReply::NetworkError code)
{
qDebug() << "Download error: " << code;
httpRequestAborted = true;
}//replyErrorActualizaciones
void updates::httpFinishedDownload()
{
if (httpRequestAborted)
{
if (file)
{
file->close();
file->remove();
delete file;
file = 0;
}
reply->deleteLater();
.
.
.
.
.
I use that class from MainWindow.cpp
MainWindow.cpp
Code:
MainWindow
::MainWindow(QWidget *parent
) : ui(new Ui::MainWindow)
{
connect(ui->actionActualizaciones,SIGNAL(triggered()),SLOT(slotCheckUpdates()));
}
.
.
.
.
void MainWindow::slotCheckUpdates()
{
updates a(this);
a.checkUpdates(version);
}//updates
I have thought a long time why it does not work and can not find the reason, I hope you could help me!
Thanks!
Re: Problems with QNetworkRequest, it does not send signals.
It does emit the signals the docs list under the conditions that the docs list. What makes you say it does not? All we have at the moment is "it doesn't work", which is not very useful.
If no data is received then readyRead() is never emitted: this could happen because, for example, the host name in the URL is wrong (I assume that is not the real URL in your code). Is replyErrorActualizaciones() being called? Even with a successful connection the server may simply close it again (server error) and send nothing back. Have you verified the request returns something outside of Qt?
Is it just that you see no data in the file you are expecting to see written? Have you verified the file is open successfully? Is it in a writeable location? if replyErrorActualizaciones() is called, regardless of error code (maybe NoError?), then httpRequestAborted will be set and the file will be deleted when the finished signal is emitted.
Re: Problems with QNetworkRequest, it does not send signals.
Sorry for not very well detailed the problem, I have problems with English because it is not my native language.
Referring to your comments:
The url is working properly, I checked by other means and it works correctly, in addition I have written the same code in another program and it works, I think that the error is because the code is written in different class of mainwindow.cpp. In the program that works, I have written the code in the file mainwindow.cpp everything.
replyErrorActualizaciones () is called. I've found that does not emit signals because I have written code in the three private slops and does not run. For example, I had written
Code:
qDebug() << "Test";
in the private slots, but it do not work.
The file has been perfect for writing, I checked it.
Re: Problems with QNetworkRequest, it does not send signals.
Try this summary of your code with the Google URL and your URL:
Code:
#include <QtCore>
#include <QtNetwork>
#include <QDebug>
static const QUrl url
("http://www.google.com");
Q_OBJECT
public:
void go() {
m_file
= new QFile("output.txt",
this);
QNetworkRequest request(url);
m_reply = m_nam.get(request);
connect(m_reply, SIGNAL(finished()), SLOT(httpFinished()));
connect(m_reply, SIGNAL(readyRead()), SLOT(httpReadyRead()));
connect(m_reply, SIGNAL(error(QNetworkReply::NetworkError)), SLOT(replyErrorActualizaciones(QNetworkReply::NetworkError)));
}
}
private slots:
void httpFinished() {
qDebug() << __func__;
m_file->close();
m_reply->deleteLater();
qApp->quit();
}
void httpReadyRead() {
quint64 bytes = m_file->write( m_reply->readAll() );
qDebug() << __func__ << "wrote" << bytes << "bytes";
}
void replyErrorActualizaciones(QNetworkReply::NetworkError code) {
qDebug() << __func__ << code;
}
private:
QNetworkAccessManager m_nam;
QNetworkReply *m_reply;
};
int main(int argc, char *argv[])
{
DoIt d;
d.go();
return app.exec();
}
#include "main.moc"
Do you see the output from the slots?
With your code, do you get warnings about connect() calls when you run it?
Re: Problems with QNetworkRequest, it does not send signals.
when the slotCheckUpdates is finished, the instances of class updates is destroyed.
All connections to that instance are invalid.
Try to keep the instance of updates as a member of the main window.
Re: Problems with QNetworkRequest, it does not send signals.
Hey thanks ChrisW67 for your code! It works correctly, but I have used your code on my program and it don't works. The problem is that the private slot "
Code:
void MainWindow::slotCheckUpdates()
" finished before of that the class updates download the file, i. e. "updates" don't have time to emit signals and download the file.(Thank you hugh_lou) How I can write a signal to work it? I have checked it with this:
Code:
void MainWindow::slotCheckUpdates()
{
updates a(this);
a.checkUpdates(version);
}//updates
and my code works correctly!
Is it possible write something for fix it, to not display the QMessageBox?
Thank you!
Added after 40 minutes:
How I can emit a signal public? I have try with this:
In updates.h
Code:
signals:
void senyal();
in updates.cpp
Code:
emit senyal(); //when I need it
the problem is that the signal is private, How I can it do?