Saving downloaded file in Qt - c++

I have my slot being called whenever someone clicks the link and I know the file is there because I can retrieve the file name and the amount of bytes the file is just not sure how to s ave it after I call the QFileDialog::getSaveFileName? I know that gives me the name of the file if the user decides to change it but how do I get the location they decide to save it in and then write it to that location.
NB: The file they will download is a word doc if that makes any difference?
void MainWindow::unsupportedContent(QNetworkReply *reply) {
qDebug() << "Left click - download!";
qDebug() << "Bytes to download: " << reply->bytesAvailable();
QString str = reply->rawHeader("Content-Disposition");
QString end = str.mid(21);
end.chop(1);
qDebug() << "string: " << end;
qDebug() << "File name: " << reply->rawHeader("Content-Disposition");
qDebug() << "File type: " << reply->rawHeader("Content-Type");
QString defaultFileName = QFileInfo(end).fileName();
QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"), defaultFileName);
if (fileName.isEmpty()) return;
QFile *file = new QFile(fileName);
file->open(fileName);
file->write(reply->read(reply->bytesAvailable()));
file->close();
}

today i explained it on another post so i will link that post here : Post
i can tell you that you have only to implement a slot that write into the file you created. and call it when readyRead() signal is emitted.

Related

How to read from QFile? It shows that file not accessible

I've been trying to read .xml file using QFile. But qt creator can't even find it, but file exists inside project (also I tried to read it from another directory, not project's, it doesn't work, too). Debuger says file not accessible.
Here's my code:
QFile file("../info.xml");
if (file.exists())
if (file.open(QFile::ReadOnly | QFile::Text))
qDebug(qPrintable("File exist"));
This is not a complete answer, but rather a list of what may have gone wrong.
Check the file path :
QFileInfo inf (file);
qDebug() << inf.QFileInfo::path();
Ensure that the file is in the right directory, i.e. in the same you have your .exe (build-ProjectName-...). You can check this by using QDir::currentPath()
Check which if causes the problem : is it the first one which checks file existence or the second one that cannot open it ?
I am not sure it is a good idea to use the QFile::Text for .xml files.
In the end, I would do something like this :
QFile file("../info.xml");
QFileInfo inf (file);
qDebug() << "File path : "<< inf.QFileInfo::path() << Qt::endl;
qDebug() << "Current path : " << QDir::currentPath() << Qt::endl;
qDebug() << "Current path (expected) : " << QDir::currentPath() + "/info.xml" << Qt::endl;
if (file.exists()){
qDebug() << "exists" << Qt::endl;
if (file.open(QFile::ReadOnly)){qDebug() << "opened";}
}

Do-while infinite loop in Qt

I'm trying to read in a file of trace addresses (each on their own line) and append to the front of each. This input file is intended to be the engine of a cache emulator i'm trying to build. I am having issues reading the file in without getting into an infinite loop. When I change the do-while to run on a false condition, I get the proper output for just the do segment. Therefore, I know I'm running into an infinite loop issue with how I worded my while segment. Maybe i'm fatigued and can't see the issue with this function:
void MainWindow::readFile(){
infoLabel->setText(tr("Invoked <b>File|Open</b>"));
QString filename="trace.txt";
QString path = QDir::currentPath();
QFile file("//Users//nathan1324//Desktop//trace.txt");
//file.open(QIODevice::ReadOnly);
if(!file.exists()){
qDebug() << "File cannot be found "<<filename;
qDebug() << " " << path;
}else{
qDebug() << filename<<" Opening...";
}
QString line;
textEdit->clear();
if (file.open(QIODevice::ReadOnly | QIODevice::Text)){
QTextStream stream(&file);
do {
line = stream.readLine();
textEdit->setText(textEdit->toPlainText()+"0x"+line+"\n");
qDebug() << "line: "<<line;
} while (!line.isNull());
}
file.close();
}
Any suggestions of an alternative way to write this function?
To add items use the append function of QTextEdit:
void QTextEdit::append(const QString & text)
Appends a new paragraph with text to the end of the text edit.
Note: The new paragraph appended will have the same character format
and block format as the current paragraph, determined by the position
of the cursor.
To iterate through the QTextStream atEnd()
bool QTextStream::atEnd() const
Returns true if there is no more data to be read from the QTextStream;
otherwise returns false. This is similar to, but not the same as
calling QIODevice::atEnd(), as QTextStream also takes into account its
internal Unicode buffer.
Code:
void MainWindow::readFile(){
infoLabel->setText(tr("Invoked <b>File|Open</b>"));
QString filename = "trace.txt";
QString path = QDir::currentPath();
QFile file("//Users//nathan1324//Desktop//trace.txt");
if(!file.exists()){
qDebug() << "File cannot be found "<<filename;
qDebug() << " " << path;
return;
}
QString line;
textEdit->clear();
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)){
qDebug() << "Could not open file" << filename;
return;
}
qDebug() << filename<<" Opening...";
QTextStream stream(&file);
while (!stream.atEnd()) {
line = stream.readLine();
if(!line.isNull()){
textEdit->append("0x"+line);
qDebug() << "line: "<<line;
}
}
file.close();
}
Use atEnd to detect the end of a stream:
bool QTextStream::atEnd() const
Returns true if there is no more data to be read from the QTextStream;
otherwise returns false. This is similar to, but not the same as
calling QIODevice::atEnd(), as QTextStream also takes into account its
internal Unicode buffer.
while (!stream.atEnd()) {
line = stream.readLine();
textEdit->setText(textEdit->toPlainText()+"0x"+line+"\n");
qDebug() << "line: "<<line;
}

How to retrieve HTTPS json data using QNetworkRequest

I have some code that successfully retrieves json content from an HTTP source:
void MainWindow::Test()
{
QNetworkRequest request;
QString filename = "http://ip.jsontest.com";
//QString filename = "https://api.github.com/users/mralexgray/repos";
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
request.setSslConfiguration(QSslConfiguration::defaultConfiguration());
request.setUrl(QUrl(filename));
QJsonObject json;
QNetworkAccessManager nam;
QNetworkReply *reply = nam.post(request, QJsonDocument(json).toJson());
while(!reply->isFinished())
{
qApp->processEvents();
}
if (reply->error() == QNetworkReply::NoError)
{
QByteArray response_data = reply->readAll();
QJsonDocument document = QJsonDocument::fromJson(response_data);
QJsonObject object = document.object();
qDebug() << "Json File Loaded : " << filename;
qDebug() << "IP: " << object["ip"].toString();
}
else // something went wrong
{
qDebug() << "Json File Failed to Load : " << filename;
qDebug() << "Error : " << reply->errorString();
}
reply->deleteLater();
}
However, when I change the URL to the HTTPS one (the line commented out in the code) I get the error "server replied: Not Found"
The HTTPS url works fine in a browser.
In my search for answers I found many different suggestions but no actual working solution.
I believe the problem is down to QT not supporting SSL 'out of the box' due to licensing issues, but here's what I've attempted so far.
I installed "Win32OpenSSL-1_0_2h.exe"
I then copied "libeay32.dll" and "ssleay32.dll" into the QT debug folder.
I added the following to the project "pro" file:
LIBS += -LC:/OpenSSL-Win32/lib -lubsec
INCLUDEPATH += C:/OpenSSL-Win32/include
I tried with and without the setSslConfiguration call.
But all this hasn't helped.
I tested SSL with the QT method:
if (QSslSocket::supportsSsl())
{
qDebug() << "Supports SSL";
}
else
{
qDebug() << "Does NOT Support SSL";
}
and that is saying "supported".
I am building the project in QT Creator, using MSVC2012 32bit settings.

Qt reading from QTextStream

I'm trying to read a text file and display the contents in a QPlainTextEdit. Please can you point out what I'm doing wrong:
QFile jsonFile("data.json");
if (!jsonFile.open(QIODevice::ReadOnly | QIODevice::Text))
{
qDebug() << "Failed to open file";
qDebug() << jsonFile.errorString();
return;
}
else
{
qDebug() << "File opened";
} //It returns that the file opened successfully
qDebug() << "File Exists?: " << jsonFile.exists(); //Yep, it exists.
QTextStream outStream(&jsonFile);
QString textString = outStream.readAll();
qDebug() << "Text string: " << textString; //textString is empty! ""
ui->fileToPost->setPlainText(textString); //fileToPost is the QPlainTextEdit
jsonFile.close();
If I do something like
QString textString = "The cat sat on the mat";
it displays fine. The problem is that nothing is being read from the stream (or maybe the file).
Try to check file's absolute path, probably it is not where, you expect it: qDebug()<<QFileInfo("data.json").absoluteFilePath();

C++ Qt - opening text file operation failure

I'm using Qt to develop my C++ application using QML as well.
Here's my code
QFile inputFile("data.txt");
//QFile inputFile("/:data.txt");
qDebug() << "Hello:";
if (!inputFile.open(QIODevice::ReadOnly | QIODevice::Text))
{
qDebug() << "Wasn't ready:";
}
else{
qDebug() << "Txt file ready:";
QTextStream in(&inputFile);
while ( !in.atEnd() )
{
QString line = in.readLine();
qDebug() << "message: " << line;
}
}
I was wondering why it doesn't work. The console always prints "Wasn't ready".
Please help.
In the error handling block where you do qDebug() << "Wasn't ready:"; you should call inputFile.error() and print out the returned value to get more details of what went wrong.
It might also be an idea to start the program with printing out the current directory, to make sure that the file is searched for in the correct location.