Opening and reading a file in Qt - c++

I am trying to use the menu bar to open a file (hardcoded) when 'File|Open' is clicked. The file should append to and display each line. My function is not finding the file. So after I click open I am getting back 'trace.txt cannot be found'. I have the file saved in the same directory as the rest of the project files. I am wondering if I haven't opened the file properly? Can anyone have a look at my code and see if you're catching an error that I am not?
void MainWindow::readFile(){
infoLabel->setText(tr("Invoked <b>File|Open</b>"));
QString filename="trace.txt";
QFile file(filename);
if(!file.exists()){
qDebug() << "File <i>cannot</i> be found "<<filename;
}else{
qDebug() << filename<<" Opening...";
}
QString line;
textEdit->clear();
if (file.open(QIODevice::ReadOnly | QIODevice::Text)){
QTextStream stream(&file);
while (!stream.atEnd()){
line = stream.readLine();
textEdit->setText(textEdit->toPlainText()+"0x"+line+"\n");
qDebug() << "line: "<<line;
}
}
file.close();
}
UPDATE:
I changed the QFile object to the direct path and that found the file. On the other hand, I am reading it in an infinite loop, which never makes it to the textEdit and continually outputs to the debugger. Any ideas?

Use current or currentPath() to see with which directory you are working.
See this example to understand the current directory:
QFile file;
QDir::setCurrent("/tmp");
file.setFileName("readme.txt");
QDir::setCurrent("/home");
file.open(QIODevice::ReadOnly); // opens "/home/readme.txt" under Unix
From http://doc.qt.io/qt-5/qfile.html#QFile

Related

Qt, C++ - Editing an existing INI file from project doesn't work when I need to save it [duplicate]

It's strange, I add desired file into the resources via Add Existing Files..., the file is there. I run qmake ("Build->Run qmake") to make the file available.
The first issue: I can't write anything into the file from output terminal! But when I manually write into the file, the output terminal shows the change every time I run it. Second issue: it still says QIODevice::read: device not open !
Here's my code:
#include <QCoreApplication>
#include <QDebug>
#include <QFile>
#include <QString>
#include <QTextStream>
#include <iostream>
void wFile(QString Filename)
{
QFile nFile(Filename);
QTextStream str(&nFile);
qDebug() << "what do you want to write in the desired file: ";
str.readLine();
if (!nFile.open(QFile::WriteOnly | QFile::Text))
{
qDebug() << "could not open the file";
return;
}
nFile.flush();
nFile.close();
}
void read (QString Filename){
QFile nFile(Filename);
if(!nFile.open(QFile::ReadOnly | QFile::Text))
{
qDebug() << "could not open file for reading";
return;
}
QTextStream in(&nFile);
QString nText = in.readAll();
qDebug() << nText;
nFile.close();
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QString nFilename =":/MyFiles/DocumentArminV.txt";
wFile(nFilename);
read(nFilename);
return a.exec();
}
And here's output terminal of the code:
The files saved in a qresource are read-only since they are part of the executable so you can not write or modify them.
docs:
Currently, Qt always stores the data directly in the executable, even on Windows, macOS, and iOS, where the operating system provides native support for resources. ...

In qt QFileDialog setsuffix is not working in linux, how to solve?

I am working on a Save dialog for my qt app. Everything works, but if no file extension is added behind the filename, it won't automatically be saved with the file extension although the filter is selected.
I know i need to set a defaultsuffix option, but even if i do, then it still won't add the extension automatically if its not given.
I found several other similar questions, where i read it works in windows but it could fail on linux distro's. If so, is there a simple workaround? Because right now, i don't have a working solution...
void MainWindow::on_actionSave_Chart_As_triggered()
{
QFileDialog *fileDialog = new QFileDialog;
fileDialog->setDefaultSuffix("files (*);;AstroQt aqt (*.aqt)");
QString fileName = fileDialog->getSaveFileName(this, "Save Radix", ui->label_2->text() +".aqt", "AstroQT(*.aqt)");
qDebug() << " save file name " << fileName << endl;
QFile file(fileName);
if (!file.open(QFile::WriteOnly | QFile::Text)) {
QMessageBox::warning(this, "Warning", "Cannot save file: " + file.errorString());
return;
}
setWindowTitle(fileName);
QTextStream out(&file);
QString text = "text that will be saved...";
out << text;
file.close();
}
Edit: After trying multiple solutions, none seemed to work. But it should have, i guess. Why else is there a aftersuffix function...? For now i solved it doing it manually. But i'm not happy with it, there should be a better solution/explanation.
// add extension if none is found.
if(!fileName.endsWith(".aqt"))
fileName.append(".aqt");
If you use the static method getSaveFileName things seems to work correctly:
#include <QFileDialog>
#include <QApplication>
#include <QDebug>
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
QString fileName = QFileDialog::getSaveFileName(
nullptr, QObject::tr("Save File"),
"teste.aqt",
QObject::tr("AstroQt (*.aqt)"));
qDebug() << " save file name " << fileName << endl;
return app.exec();
}
I get the correct file name with the extension, if I type something without the extension.
If you take a look at QFileDialog documentation, you will see that getSaveFileName() is an static function. Because of this, there is no way for this method to access a member of the instance of the class that makes use of setDefaultSuffix(). So whatever you set in fileDialog->setDefaultSuffix(...) has nothing to do with what the getSaveFileName() function does.
In ordertTo make it work, you have to run the dialog directly from the instance. You should do something like this:
QFileDialog fileDialog(this, "Choose file to save");
fileDialog.setDefaultSuffix("json");
fileDialog.setNameFilter("json-files (*.json)");
fileDialog.exec();
QFile f(fileDialog.selectedFiles().first());
QFileInfo fileInfo(f);
QString FILE_NAME(fileInfo.fileName());

Not able to reproduce the notepad example in qt; read access violation

I'm learning Qt following this link.
When trying to open a file through function member open I get the error:
Exception thrown: read access violation.
this was 0xFFFFFFFFFFFFFFFF.
This is the definition of the function:
Notepad::open(){
QString fileName = QFileDialog::getOpenFileName(this, "Open File", "", "Text Files (*.txt);;C++ Files (*.cpp *.h");
if (fileName != "") {
QFile file(fileName);
if (!file.open(QIODevice::ReadOnly)) {
QMessageBox::critical(this, "Error", "Could not open file");
}
QTextStream in(&file);
textEdit->setText(in.readAll());
//textEdit->setText("test 1a2b");
file.close();
}
}
Can anybody see the problem?

Why qt does not read a file

I have the following lines of code:
QFile file("1.txt");
qDebug() << file.readAll();
The file is locating in project directory. When I compile the code, I get:
"QIODevice::read (QFile, "1.txt"): device not open"
You must open the file before reading.
As a starting point (from the documentation):
QFile file("in.txt");
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
return;
while (!file.atEnd()) {
QByteArray line = file.readLine();
process_line(line);
}
Other options can be found here.

Qt select existing file

I am new to Qt and I want to be able to select a already existing file called default.ini which is in the same directory as the exe. I already have some code that allows me to do that, but the user has to manually select the file everytime.
QString file = QFileDialog::getOpenFileName(this, tr("Open File"), "/debug", tr("default (*.ini)"));
if (file != NULL) {
try {
controller_->ConfigurationFileSave(file.toStdString());
} catch (std::exception &e) {
Logger::Log(std::string("Failed to save configuration: ") + e.what(),
Logger::kError);
}
}
The program does everything I want it to do in terms of writing/ reading to the file, I just don't want the program to require any user input in opening the file. I understand that the reason I have user input is because I am using the QFileDialog class and I just want to know if there is another class that does it automatically. Thanks
Edit 1 As per Arun's suggestion I tried to use Qfile. The program now reads from the default.ini config file successfully but it won't save to the config file. Is there an easy way to write to the file?
QFile file("default.ini");
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
return;
QString content = file.readAll();
file.close();
if (content != NULL) {
try {
controller_->ConfigurationFileSave(content.toStdString());
} catch (std::exception &e) {
Logger::Log(std::string("Failed to save configuration: ") + e.what(),
Logger::kError);
}
}
Edit 2 As per Arun's second suggestion:
QFile file("default.ini");
file.open(QIODevice::ReadOnly | QIODevice::Text);
QString line = file.readAll();
file.close();
file.open(QIODevice::WriteOnly | QIODevice::Text);
try {
controller_->ConfigurationFileSave(line.toStdString());
} catch (std::exception &e) {
Logger::Log(std::string("Failed to save configuration: ") + e.what(),
Logger::kError);
}
file.close();
Your file chooser code was passing a filename to ConfigurationFileSave(). Here's code to get that file name without interaction:
QDir appDir(QCoreApplication::applicationDirPath());
QFileInfo file(appDir, "default.ini");
// file.filePath() or file.absoluteFilePath() here:
controller_->ConfigurationFileSave( ___HERE___ );
You can test this in QtCreator by creating a new console application and using this as your main.c:
#include <QCoreApplication>
#include <QDebug>
#include <QFileInfo>
#include <QDir>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QDir appDir(QCoreApplication::applicationDirPath());
QFileInfo file(appDir, "default.ini");
qDebug() << " " << file.filePath();
qDebug() << " " << file.absoluteFilePath();
return 0;
}
Output:
silver:qt_app_dir hchapman$ ls
Makefile main.cpp main.o qt_app_dir qt_app_dir.pro qt_app_dir.pro.user
silver:qt_app_dir hchapman$ ./qt_app_dir
"/Users/hchapman/Desktop/qt_app_dir/default.ini"
"/Users/hchapman/Desktop/qt_app_dir/default.ini"
silver:qt_app_dir hchapman$ cd ..
silver:Desktop hchapman$ ./qt_app_dir/qt_app_dir
"/Users/hchapman/Desktop/qt_app_dir/default.ini"
"/Users/hchapman/Desktop/qt_app_dir/default.ini"
silver:Desktop hchapman$
Here is a typical example of how you can do file I/O without using QFileDialog.
This example here uses QFile
QFile file("default.ini");
if (!file.open(QIODevice::ReadWrite | QIODevice::Text))
return;
while (!file.atEnd()) {
QByteArray line = file.readLine();
process_line(line);
}