QNetworkRequest to download an image? - qt

I have used QNetworkRequest to retrieve xml off the web without problems:
request.setUrl(QUrl("http://api.somesite.com/api/4we35r/somefile.xml"));
myNetworkAccessManager->get(request);
How would I go about downloading an image? Ex:
http://www.mysite.com/27eye28/images/myimage.png
Do I just replace the xml url above with the png url? Do I have to do anything special?

Yes, replacing the URL is all that you have to do.
Here's a working example,
void MainWindow::GetImage(QString url)
{
QNetworkAccessManager* manager = new QNetworkAccessManager(this);
connect(manager, SIGNAL(finished(QNetworkReply *)), this, SLOT(replyFinished(QNetworkReply *)));
QUrl url = QUrl(url);
QNetworkRequest request(url);
manager->get(request);
}
void MainWindow::replyFinished(QNetworkReply *reply)
{
if(reply->error() != QNetworkReply::NoError)
{
ui->textBrowser->setText("Error: " + reply->errorString());
}
else
{
QByteArray responseData = reply->readAll();
QFile file("d:\\myImage.png");
file.open(QIODevice::WriteOnly);
file.write((responseData));
file.close();
}
}

Related

Error transferring https://speech.googleapis.com/v1/speech:recognize?key=,myKey> - server replied: Bad Request [Problem on Windows OS]

I am using google speech-to-text api to convert my audio file to text. Following is my code(in Qt):
`QString fileName = QDir::currentPath() + "/audio.wav"; //this is my audio file
QFile audioFile(fileName);
if(!audioFile.open(QIODevice::ReadOnly | QIODevice::Text)){
QMessageBox::critical(0,"Error",fileName+" Not found!");
ui->pushButton_4->setText("Speech to text");
return;
}
int idx = ui->comboBox->currentIndex();
QString enc;
if (idx == -1)
enc = "en-US";
else
enc = ui->comboBox->itemData(idx).toString(); //Language selected by user
QByteArray audioData=audioFile.readAll();
QUrl url("https://speech.googleapis.com/v1/speech:recognize");
QUrlQuery query;
query.addQueryItem("key","myKeyHere...");
url.setQuery(query);
QNetworkRequest request(url);
request.setHeader(QNetworkRequest::ContentTypeHeader,"audio/x-flac");
QJsonObject json;
QJsonObject config;
config["encoding"]="FLAC";
config["sampleRateHertz"]=44100;
config["languageCode"]=enc;
json["config"]=config;
QJsonObject audio;
audio["content"]=QString::fromLatin1(audioData.toBase64());
json["audio"]=audio;
QByteArray jsonData=QJsonDocument(json).toJson();
QNetworkAccessManager *manager=new QNetworkAccessManager();
QNetworkReply *reply=manager->post(request,jsonData);
QObject::connect(reply,&QNetworkReply::finished,[this,reply](){
if(reply->error()!=QNetworkReply::NoError){
QMessageBox::critical(0,"Error Occured",reply->errorString());
qDebug() << reply->readAll();
ui->pushButton_4->setText("Speech to text");
return;
}
else if(reply->error()==QNetworkReply::UnknownNetworkError){
QMessageBox::warning(0,"Network Error","Please check your internet connection and try again!");
ui->pushButton_4->setText("Speech to text");
}
else if(reply->isFinished() && reply->error()==QNetworkReply::NoError){
QJsonDocument responseJson=QJsonDocument::fromJson(reply->readAll());
QJsonObject object=responseJson.object();
QString ResponseText=object["results"].toArray()[0].toObject()
["alternatives"].toArray()[0].toObject()["transcript"].toString();
QTextCursor cur = curr_browser->textCursor();
qDebug() << "Response Data :" << ResponseText;
cur.insertText(ResponseText);
ui->pushButton_4->setText("Speech to text");
}
reply->deleteLater();
});`
This code is working perfectly on Ubuntu but not on windows. When i run this on Ubunutu, i am receiving the response, but on windows i receive the following error:
Error transferring https://speech.googleapis.com/v1/speech:recognize?key=,myKey> - server replied: Bad Request
Following is the code to record an audio file:
`if (m_audioRecorder->state() == QMediaRecorder::StoppedState) {
QString fileName = QDir::currentPath() + "/audio.wav";
m_audioRecorder->setOutputLocation(QUrl::fromLocalFile(fileName));
qDebug()<<"Recording your audio!!";
ui->pushButton_4->setText("Stop ?");
QAudioEncoderSettings settings;
settings.setCodec("audio/x-flac");
settings.setSampleRate(0);
settings.setBitRate(0);
settings.setChannelCount(1);
settings.setQuality(QMultimedia::EncodingQuality(2));
settings.setEncodingMode(QMultimedia::ConstantQualityEncoding);
m_audioRecorder->setEncodingSettings(settings, QVideoEncoderSettings(), "");
m_audioRecorder->record();
}
else {
qDebug()<<"stopped your recording!";
ui->pushButton_4->setText("Processing ...");
m_audioRecorder->stop();
speechToTextCall(); //calling the code to send request to google api
}`
Can anyone help please?
I tried changing the encodig and container type, but nothing worked on Windows.
I have found the solution of above problem. Windows does not recognize the auido/x-flac encoding so i modified my encoding code as follows:
'
#ifdef Q_OS_WIN
settings.setCodec("audio/pcm");
#else
settings.setCodec("audio/x-flac");
#endif
'
I made the same changes at other two places where encoding was set and it worked on windows as well.

QNetworkReply::RemoteHostClosedError

I was learning the Github API and wanted to create an Issue on github by Qt.
But, when I submit my Issue, the "Debug Console" said
QNetworkReply::RemoteHostClosedError
(I catched error).
I don't know why, please help me!
Code on Github:
void MainWindow::on_pushButton_2_clicked()
{
QString id = ui->ID_Send->text();
QJsonObject JJ;
QJsonDocument jd;
JJ["title"] = ui->Title->text();
JJ["body"] = ui->Comment->toPlainText();
QHttpMultiPart *part = new QHttpMultiPart(QHttpMultiPart::FormDataType);
QHttpPart info;
info.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("text/json"));
jd.setObject(JJ);
info.setBody(jd.toJson());
part->append(info);
QNetworkRequest request;
qDebug()<<"https://api.github.com/repos/MoyuSteve/Comment/issues?client_id="+
client_id+"&client_secret="+client_secret;
request.setUrl(QUrl("https://api.github.com/repos/MoyuSteve/Comment/issues?client_id="+
client_id+"&client_secret="+client_secret));
QNetworkReply* reply = manager->post(request,part);
QObject::connect(reply, &QNetworkReply::finished, [reply, this] () {
if (reply->error() == QNetworkReply::NoError) {
ui->status->setText("ok");
} else {
ui->status->setText("failed");
qDebug()<<reply->error();
}
reply->deleteLater();
});
}
You can take example in this answer or here.
Compared to your code, it sets the header to "application/json".
And it uses a QNetworkAccessManager to send network requests and receive replies.
QUrl url("https://api.github.com/repos/" + owner +"/" + project + "/tags");
qInfo() << url.toString();
QNetworkRequest request(url);
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
QNetworkAccessManager nam;
QNetworkReply * reply = nam.get(request);

QT download video with SSL not working

This code downloads a video, but for some reason does not work
globals.h
QString videoDirectLink = "";
mainwindow.cpp
#include "globals.h"
void MainWindow::readOutput() {
QByteArray outData = myProcess->readAllStandardOutput(); // read from CMD
videoDirectLink = outData; // videoDirectLink Contains https://media08.vbox7.com/s/91/91f4c651car96dafe736.mp4
if (videoDirectLink.contains("https")) {
// SSL downloading
QNetworkAccessManager *manager2 = new QNetworkAccessManager(this);
connect(manager2, SIGNAL(finished(QNetworkReply*)), this, SLOT(downloadFinished(QNetworkReply*)));
QNetworkRequest *req = new QNetworkRequest();
req->setUrl(QUrl(videoDirectLink)); //videoDirectLink
QSslConfiguration configSsl = QSslConfiguration::defaultConfiguration();
configSsl.setProtocol(QSsl::AnyProtocol);
req->setSslConfiguration(configSsl);
connect(manager2->get(*req), SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(downloadProgress(qint64,qint64)));
}
If changes req->setUrl(QUrl(videoDirectLink));
to req->setUrl(QUrl("https://media08.vbox7.com/s/91/91f4c651car96dafe736.mp4"));
or
QString n ="https://media08.vbox7.com/s/91/91f4c651car96dafe736.mp4";
req->setUrl(QUrl(n));
everything works
This is worked code for download without SSL. The principle is the same
globals.h
QString videoDirectLink = "";
mainwindow.cpp
#include "globals.h"
QNetworkAccessManager *manager = new QNetworkAccessManager(this);
// start downloading
connect(manager, SIGNAL(finished(QNetworkReply*)),
this, SLOT(downloadFinished(QNetworkReply*)));
QString target = videoDirectLink;
QUrl url = QUrl::fromEncoded(target.toLocal8Bit());
connect(manager->get(QNetworkRequest(url)), SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(downloadProgress(qint64,qint64)));
I tried to add encoding, but that is not the problem.
other suggestions ?
// NOT WORKING
void MainWindow::readOutput() {
QString outData = myProcess->readAllStandardOutput(); // URL -> https://www.vbox7.com/play:91f4c651ca
videoDirectLink = outData; // videoDirectLink -> https://media28.vbox7.com/s/91/91f4c651car96dafe736.mp4
if (videoDirectLink.contains("https")) {
QNetworkAccessManager *manager2 = new QNetworkAccessManager(this);
connect(manager2, SIGNAL(finished(QNetworkReply*)), this, SLOT(downloadFinished(QNetworkReply*)));
QNetworkRequest *req = new QNetworkRequest();
req->setUrl(QUrl(videoDirectLink)); //videoDirectLink
connect(manager2->get(*req), SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(downloadProgress(qint64,qint64)));
QMessageBox::information(this,"SSL downloading",videoDirectLink,"ok"); // displays https://media28.vbox7.com/s/91/91f4c651car96dafe736.mp4
}
}

How can I read the body from QNetworkReply if code is not 200

Reply returns empty body content if reply->error() != QNetworkReply::NoError,
but actually response has a content.
How can I read it?
void MainWindow::on_pushButton_clicked()
{
manager = new QNetworkAccessManager(this);
connect( manager, SIGNAL(finished(QNetworkReply*)),
this, SLOT(replyFinished(QNetworkReply*)));
manager->get(QNetworkRequest(QUrl("http://...")));
}
void MainWindow::replyFinished(QNetworkReply* reply)
{
if (reply->error() == QNetworkReply::NoError)
{
QByteArray content= reply->readAll();
QDebug() << QString body(content); // ok
} else {
QByteArray content= reply->readAll();
QDebug() << QString body(content); //empty, but must be exist
}
}

Qt HTTP GET freezes screen

I'm writing a Qt program to get an image from site and insert in a QLabel. When I send my request my screen freezes and nothing more occurs.
Notice I'm new in Qt.
Based on my initial knowledge of Qt it's enough send a signal when download is finished.
...
MapReader::MapReader(QWidget *parent, Qt::WFlags flags)
: QMainWindow(parent, flags)
{
ui.setupUi(this);
imageLabelMap = ui.imageMap;
getImageButton = ui.getImageButton;
networkManager = new QNetworkAccessManager(this);
setup();
}
MapReader::~MapReader()
{
}
void MapReader::setup()
{
QObject::connect(getImageButton, SIGNAL(clicked()), this, SLOT(triggerDownload()));
QObject::connect(networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(finishedDownload(QNetworkReply*)));
}
void MapReader::setImage(QByteArray imageBytes)
{
QImage map;
...
}
void MapReader::triggerDownload()
{
QUrl url("http://images.tsn.ca/images/stories/2012/09/26/terrydunfield_2035-430x298.jpg");
QNetworkReply* reply = networkManager->get(QNetworkRequest(url));
QObject::connect(reply, SIGNAL(readyRead()), &loop, SLOT(quit()));
}
void MapReader::finishedDownload(QNetworkReply* reply)
{
reply->deleteLater();
QVariant statusCodeV = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
QVariant redirectionTargetUrl = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
if(reply->error() != QNetworkReply::NoError)
{
QMessageBox msgBox;
msgBox.setWindowTitle("Error");
msgBox.setInformativeText("Error on downloading file: \n"+reply->errorString());
msgBox.exec();
return;
}
QVariant attribute = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
if (attribute.isValid())
{
QUrl url = attribute.toUrl();
qDebug() << "must go to:" << url;
return;
}
setImage(reply->readAll());
}
I think there is some code missing that might give us a clue. You have
QObject::connect(reply, SIGNAL(readyRead()), &loop, SLOT(quit()));
But I don't see where loop is defined? Sounds like you are running an additional event loop?
Regardless, you don't need that. This should be as simple as:
void MapReader::triggerDownload()
{
QUrl url("http://images.tsn.ca/images/stories/2012/09/26/terrydunfield_2035-430x298.jpg");
QNetworkReply* reply = networkManager->get(QNetworkRequest(url));
QObject::connect(reply, SIGNAL(finished()), this, SLOT(finishedDownload()));
}
void MapReader::finishedDownload()
{
QNetworkReply *reply = qobject_cast<QNetworkReply *>(sender()); // sender() allows us to see who triggered this slot - in this case the QNetworkReply
QVariant statusCodeV = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
QVariant redirectionTargetUrl = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
if(reply->error() != QNetworkReply::NoError)
{
QMessageBox msgBox;
msgBox.setWindowTitle("Error");
msgBox.setInformativeText("Error on downloading file: \n"+reply->errorString());
msgBox.exec();
return;
}
QVariant attribute = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
if (attribute.isValid())
{
QUrl url = attribute.toUrl();
qDebug() << "must go to:" << url;
return;
}
setImage(reply->readAll());
reply->deleteLater();
}
Make sure you have defined finishedDownload() as a slot in your header file

Resources