Qt Creator combobox - c++

How to write Combobox current text in a preexisting text file in hard drive? Here is my code:
void second::on_pushButton_4_clicked()
{
QFile file("vik.txt");
if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
return;
QTextStream out(&file);
out << ui->comboBox_5->currentText() << "\n";
}

Maybe you forgot to close the file
void second::on_pushButton_4_clicked()
{
// Get comboBox text value
QString txt = ui->comboBox_5->currentText();
// Open file for writing
QFile file("vik.txt");
file.open(QIODevice::WriteOnly | QIODevice::Text);
QTextStream out(&file);
// Write in file
out << txt << "\n";
// Close file
file.close();
}

You have several issues in your code, let me enumerate them one-by-one:
You need this flag for "overwrite" as per your comment:
QIODevice::Truncate 0x0008 If possible, the device is truncated before it is opened. All earlier contents of the device are lost.
More importantly, have you checked whether the method returns after open with some error? If it does, please print out file.errorString() there:
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
qDebug() << file.errorString();
return;
}
On the most important note, you are likely facing the issue that the file is not in your current working directory. If the file resides beside the application executable, please change the corresponding line into your code to this:
QFile file(QCoreApplication::applicationDirPath() + "/vik.txt");

Related

Converting valid QFile to QString - QString is empty

So I am trying to convert a QFile into a QString by doing the following:
void MainWindow::openTemplateFile(QString location)
{
if (location.isEmpty())
return;
else
{
QString variable;
templateFile.setFileName(location);
if (!templateFile.open(QFile::ReadOnly | QFile::Text))
{
QMessageBox::information(this, "Unable to open template",
templateFile.errorString());
return;
}
else // file opened and ready to read from
{
QTextStream in(&templateFile);
QString fileText = in.readAll();
qDebug() << templateFile.size() << in.readAll();
}
}
}
However, in I get the following result in the debug console:
48 ""
templateFile does exist and is part of the MainWindow class. This is also simplified code - in the actual program I read chars from the file and it works correctly. The location string is a result of the QFileDialog::getOpenFileName function, which I open a txt file with.
You call readAll() twice. The second time, the stream is positioned at end-of-file, and so readAll() has nothing to read and returns an empty string. Print fileText in your debug output instead.

QT Creator - Parsing through CSV file

OK, so I am using QT Creator for C++ and I am making a function that allows me to parse through the CSV file that I have named getExcelFile. Everything else is working fine but my code will not enter my while loop for some reason which is driving me crazy. Some suggestions would be helpful! Thanks.
void Widget::getExcelFile(){
//Name of the Qfile object.
//filename is the directory of the file once it has been selected in prompt
QFile thefile(filename);
//If the file isn't successfully open
if (thefile.open(QIODevice::ReadOnly | QIODevice::Text)){
qDebug() << "File opened successfully";
//Converts text file to stream
QTextStream in(&thefile);
fileContent=in.readAll();
QString line;
while (!in.atEnd()){
//line = textStream.readLine();//reads line from file
//Will not enter this loop for some odd reason.
qDebug() << "This text does not print out";
}
}
qDebug() << "This prints out successfully";
ui->textEdit->setPlainText(fileContent);
}
You did in.readAll(), after that call in.atEnd() will return true. Either remove in.readlAll() or while loop, why do you need both?

How to recursively write data to a text file in C++/ Qt

I have a C++\Qt program that scans the files in a particular directory. I'm trying to write the paths to the files contained therein in a text file, but all I've managed to do is write the path to the last file.
void ScanDir::qDirIteratorScanner(QString path)
{
QDirIterator it(path, QStringList() << "*.mp4", QDir::Files, QDirIterator::Subdirectories);
while (it.hasNext())
{
WriteToFile writeToFile(path, it.next());
qDebug() << "it.next()";
}
}
...
WriteToFile::WriteToFile(QString path, QString data)
{
path += "/Data.txt";
QFile file(path);
if (file.open(QFile::ReadWrite)) {
QTextStream stream(&file);
stream << data << endl;
}
}
How can I write all the paths into the text file?
You're creating a QFile in read/write mode at each call of WriteToFile: this is truncating the contents of the file, so only contents written by the last call will remain.
Try:
void ScanDir::qDirIteratorScanner(QString path)
{
QDir dir(path);
QFile file(dir.absoluteFilePath("Data.txt"));
if (file.open(QFile::ReadWrite)) {
QTextStream stream(&file);
QDirIterator it(
dir,
QStringList() << "*.mp4",
QDir::Files,
QDirIterator::Subdirectories
);
while (it.hasNext())
{
stream << it.next() << endl;
}
}
}
Here the file is opened only once. If you want/need to keep a function WriteToFile, pass stream as an additional parameter (by reference).
Note:
As proposed by Simon Kraemer in the comments, I used QDir::absoluteFilePath as it makes it easier to prevent missing or accidental slashes in the path.
An alternative to keep your design may be to use QFile::Append mode:
void ScanDir::qDirIteratorScanner(QString path)
{
QDir dir(path);
// reset the file
{
QFile file(dir.absoluteFilePath("Data.txt"));
file.open(QFile::ReadWrite);
}
QDirIterator it(
dir,
QStringList() << "*.mp4",
QDir::Files,
QDirIterator::Subdirectories
);
while (it.hasNext())
{
WriteToFile writeToFile(path, it.next());
qDebug() << "it.next()";
}
}
WriteToFile::WriteToFile(QString path, QString data)
{
QDir dir(path);
QFile file(dir.absoluteFilePath("Data.txt"));
if (file.open(QFile::Append)) {
QTextStream stream(&file);
stream << data << endl;
}
}
Each time you open the file and write one line to it, overwriting whatever is in the file. Instead, try opening it in append mode, this should cause whatever you write to be added at the end of the file.
QTextStream stream(&file,QIODevice::Append);
You must open the file in "append" mode, otherwise you will override its content every time you open the file:
file.open(QFile::Append)
2 remarks to your code:
Writing to a file from a constructor seems questionable. Why don't you just declare a function?
Why don't you open the file just once?
void ScanDir::qDirIteratorScanner(QString path)
{
QFile file(QDir(path).absoluteFilePath("Data.txt"));
if(file.open(QFile::WriteOnly))
{
QTextStream stream(&file);
QDirIterator it(path, QStringList() << "*.mp4", QDir::Files, QDirIterator::Subdirectories);
while (it.hasNext())
{
stream << it.next() << endl;
qDebug() << "it.next()";
}
}
}
It would be most efficient to move the file opening and writing to qDirIteratorScanner() instead of WriteToFile(). This way you can open the file, write everything, then close the file.
What you have now is you keep on opening (and overwriting) the same file on every iteration. That's why you are only left with the last write. Alternatively, you could open the file with the QIODevice::Append flag, but that's just unnecessary operations compared to the first suggestion, where you will open the file only once to write everything.

how to write to multiple files one after another in qt?

my program needs to write to multiple files one after the other stored in folder... i hav used foreach statement to open a files ... bt when i am trying to write to it... its nt working...
my code for writing files is..
QString path = ui->pathBox->text();
QDir mydir(path);
QStringList filter("*.txt");
foreach (QString filename,mydir.entryList(filter,QDir::Files))
{
QFile ofil(filename);
if(!ofil.open(QIODevice::Append | QIODevice::Text))
{
qDebug() << "The file could not opened";
return;
}
QTextStream ostream(&ofil);
QString name = ui->nameBox->text();
ostream << name;
ofil.flush();
ofil.close();
}
plz tell me the correct way to write it????

QFile and QTextStream for a logger class

I'm trying to create a Logger class using QFile and QTextStream but I can't find an efficient way of doing it. I just want to create a log(...) function in it.
I know it works if I do the following:
void CLogger::log(QString strLog,int nType) {
QFile file(m_strFileName);
file.open( QIODevice::Append | QIODevice::Text );
QTextStream logStream(&file);
logStream << nType << "-" << strLog;
file.close();
}
But It is quite nasty. I don't want to create a QFile object at every log line I insert.
So from that, I tried several different ways like:
1) (with QFile *m_pFile as member)
CLogger::CLogger()
{
m_pFile = new QFile(m_strFileName);
}
void CLogger::log(QString strLog,int nType)
{
m_pFile->open( QIODevice::Append | QIODevice::Text );
QTextStream logStream(m_pFile);
logStream << nType << "-" << strLog;
m_pFile.close();
}
or
2) (with QFile *m_pFile and QTextStream *m_pLogStream as members)
CLogger::CLogger()
{
m_pFile = new QFile(m_strFileName);
m_pFile->open( QIODevice::Append | QIODevice::Text );
m_pLogStream = new QTextStream(m_pFile);
}
void CLogger::log(QString strLog,int nType)
{
*m_pLogStream << nType << "-" << strLog;
}
In the first case, I get:
C2248: 'QTextStream::QTextStream' : cannot access private member
declared in class 'QTextStream'
in the 2nd, *m_pLogStream is not equivalent to a QTextStream&.
What am I doing wrong?
Actually it is not such a bad solution to open (and close) the log file every time you need to log something (unless you log 1000 times every second... but then noone would be able to process that amount of data ...). This not only allows you to have a very stable log (since you do not keep the file open all the time, so you are no depending on the flushing of the oeprating system), but also would allow you to be able to implement features as log rolling, and other niceties.
If you keep the log file open, in case of an unwanted "crash" you might not get all the log lines, depending of course how your OS is handling this ungraceful exits.
Here is a piece of code we use for logging:
QMutexLocker locker(&m_lineLoggerMutex);
QFile f(getLogFileName());
doRollLogsIfNeeded(static_cast<qint64>(f.size() + lineToBelogged.length()));
// Do not open in append mode but seek() to avoid warning for unseekable
// devices, note that if open is made with WriteOnly without Append, the
// file gets truncated
if (!f.open(QIODevice::ReadWrite | QIODevice::Text))
{
QTextStream out(stdout);
out << "CANNOT OPEN LOG FILE: " << getLogFileName();
return;
}
// seek() does nothing on sequential devices, this is in essence what QFile
// does when Append flag is set in open() but without warning (on Qt 4.8.3)
// However, Qt 4.8.1 issues the warning, so check it explicitly
if (!f.isSequential())
{
f.seek(f.size());
}
QTextStream out(&f);
out << lineToBelogged;
This goes in a method, and the destructors take care of the closing of the devices.