Renaming files with Qt - qt

I'm trying to write a program that renames a certain list of files in a chosen directory with a new extension. Pretty much to replace all .dx90 files with .dx80 files. This is the code that I've written so far and it's not working. All the files are being placed into the failed files list but I'm getting no errors.
#include <QFileDialog>
#include <QString>
#include <QApplication>
#include <QDir>
#include <QStringList>
#include <QTextStream>
QTextStream cout(stdout);
int main(int argc, char* argv[])
{
QApplication app(argc, argv);
QString dirName = QFileDialog::getExistingDirectory(0, "Open Directory", QDir::currentPath(), QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
QDir directory(dirName);
QStringList filters;
filters << "*.dx90";
QStringList files = directory.entryList(filters);
QStringList changedFiles, failedFiles;
foreach(QString filename, files)
{
QFileInfo info(filename);
QString rawFileName = filename.section(".", 0, 0);
QString newName = info.absoluteFilePath().section("/", 0, -2) + "/" + rawFileName + ".dx80";
bool success = directory.rename(info.absoluteFilePath(), newName);
if(success)
{
changedFiles << info.absoluteFilePath();
}
else
{
failedFiles << info.absoluteFilePath();
}
}
return 0;
}

I figured it out. The error I made was in the line:
QFileInfo info(filename);
It was not finding the file as the variable filename was not the absolute path. This made the info variable default to the QFileInfo of the current working directory of the application. I fixed the code by changing that line to:
QFileInfo info(directory.absolutePath() + "/" + filename);
Thanks to anyone that tried to help me fix the code. I hope this helps others that have similar problems.

Related

QFileDialog created without file extension in linux

I am creating a file in both windows and linux using QFileDialog
fileName = QFileDialog::getSaveFileName(this, tr("Create project"), applicationPath,tr("Files (*.MSC)"));
In windows the file is created as path/to/file.MSC
but in linux file is created as path/to/file
why .MSC is not appending in Linux, whether we need to use other function for this
The following example works fine on Linux. You get the file myfile.MSC with the text "test" written on it.
#include <iostream>
#include <QApplication>
#include <QFileDialog>
#include <QString>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QString applicationPath = QDir::currentPath() + "/myfile.MSC";
QString fileName = QFileDialog::getSaveFileName(0,
QApplication::tr("Create project"),
applicationPath,
QApplication::tr("Files (*.MSC)"));
if (fileName.isEmpty())
return -1;
else {
QFile file(fileName);
if (!file.open(QIODevice::WriteOnly)) {
std::cout << "error\n";
return -1;
}
QDataStream out(&file);
out << "test";
}
return a.exec();
}

Qt is successfully creating a file but not writing to it with QTextStream

Hey I'm trying to mess around with Qt and for some reason the following code will create the desired text file, but never writes anything to it. Am I doing something wrong? I believe I've copied the example in the documentation pretty accurately.
qDebug() << output
works as expected, but even though the file is created, nothing is ever written to it.
#include <QCoreApplication>
#include <QtDebug>
#include <QString>
#include <QDateTime>
#include <QTextStream>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QString filename = "";
filename.append(QString::number(QDateTime::currentMSecsSinceEpoch()));
filename.append(".txt");
QFile file(filename);
file.open(QIODevice::WriteOnly);
QTextStream out(&file);
QString output = "TEST";
qDebug() << output;
out << output;
return a.exec();
}
The data does not get written to disk immediately: It sits in a buffer until it's flushed.
Close the file after you've finished writing.
(In my experience, the file is closed anyway when you quit the program, but it's good practice to do this explicitly)

Check if directory is empty

I'm trying to check if a directory is empty.
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QDir Dir("/home/highlander/Desktop/dir");
if(Dir.count() == 0)
{
QMessageBox::information(this,"Directory is empty","Empty!!!");
}
}
Whats the right way to check it, excluding . and ..?
Well, I got the way to do it :)
if(QDir("/home/highlander/Desktop/dir").entryInfoList(QDir::NoDotAndDotDot|QDir::AllEntries).count() == 0)
{
QMessageBox::information(this,"Directory is empty","Empty!!!");
}
Since Qt 5.9 there is bool QDir::isEmpty(...), which is preferable as it is clearer and faster, see docs:
Equivalent to count() == 0 with filters QDir::AllEntries | QDir::NoDotAndDotDot, but faster as it just checks whether the directory contains at least one entry.
As Kirinyale pointed out, hidden and system files (like socket files)
are not counted in highlander141's answer.
To count these as well, consider the following method:
bool dirIsEmpty(const QDir& _dir)
{
QFileInfoList infoList = _dir.entryInfoList(QDir::AllEntries | QDir::System | QDir::NoDotAndDotDot | QDir::Hidden );
return infoList.isEmpty();
}
This is one way of doing it.
#include <QCoreApplication>
#include <QDir>
#include <QDebug>
#include <QDesktopServices>
int main(int argc, char *argv[])
{
QCoreApplication app(argc,argv);
QDir dir(QDesktopServices::storageLocation(QDesktopServices::DesktopLocation));
QStringList list = dir.entryList();
int count;
for(int x=0;x<list.count(); x++)
{
if(list.at(x) != "." && list.at(x) != "..")
{
count++;
}
}
qDebug() << "This directory has " << count << " files in it.";
return 0;
}
Or you could just check with;
if(dir.count()<3){
... //empty dir
}

Recursive search for directory returning incorrect value

Having a problem returning the correct value from a recursive search for a directory. The code is below
#include <QCoreApplication>
#include <QDir>
#include <QString>
#include <QDebug>
static QString findDirectoryPathFromId(const QString &startPath, const QString &id)
{
QDir dir(startPath);
QFileInfoList list = dir.entryInfoList(QDir::AllDirs | QDir::NoDotAndDotDot | QDir::NoSymLinks);
QString path;
foreach(QFileInfo dinfo, list)
{
if (dinfo.fileName() == id)
{
qDebug() << "****************Found****************" << dinfo.filePath();
return dinfo.filePath();
}
else
{
findDirectoryPathFromId(dinfo.absoluteFilePath(), id);
}
}
return QString();
}
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
QStringList args = app.arguments();
QString path = findDirectoryPathFromId("/home/project/dirtest", args.at(1));
qDebug() << "Return path" << path;
return 0;
}
The function finds the directory as the "Found" debug statement is printed, however the return value is a null string.
Could someobody explain what I'm doing wrong here.
Thanks
I think I've fixed it.
I need to check if the recursive call has found the directory and return it.
path = findDirectoryPathFromId(dinfo.absoluteFilePath(), id);
if (!path.isNull())
return path;
Is this correct.

Save QList<int> to QSettings

I want to save a QList<int> to my QSettings without looping through it.
I know that I could use writeArray() and a loop to save all items or to write the QList to a QByteArray and save this but then it is not human readable in my INI file..
Currently I am using the following to transform my QList<int> to QList<QVariant>:
QList<QVariant> variantList;
//Temp is the QList<int>
for (int i = 0; i < temp.size(); i++)
variantList.append(temp.at(i));
And to save this QList<Variant> to my Settings I use the following code:
QVariant list;
list.setValue(variantList);
//saveSession is my QSettings object
saveSession.setValue("MyList", list);
The QList is correctly saved to my INI file as I can see (comma seperated list of my ints)
But the function crashes on exit.
I already tried to use a pointer to my QSettings object instead but then it crashes on deleting the pointer ..
QSettings::setValue() needs QVariant as a second parameter. To pass QList as QVariant, you have to declare it as a Qt meta type. Here's the code snippet that demonstrates how to register a type as meta type:
#include <QCoreApplication>
#include <QDebug>
#include <QMetaType>
#include <QSettings>
#include <QVariant>
Q_DECLARE_METATYPE(QList<int>)
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
qRegisterMetaTypeStreamOperators<QList<int> >("QList<int>");
QList<int> myList;
myList.append(1);
myList.append(2);
myList.append(3);
QSettings settings("Moose Soft", "Facturo-Pro");
settings.setValue("foo", QVariant::fromValue(myList));
QList<int> myList2 = settings.value("foo").value<QList<int> >();
qDebug() << myList2;
return 0;
}
You might have to register QList as a meta-type of its own for it to work. This is a good starting point to read up on meta-types in Qt: http://qt.nokia.com/doc/4.6/qmetatype.html#details .
I was also struggling with this ... and I believe I now have a decent solution.
I hope this saves someone the trouble, it caused me.
#include <QCoreApplication>
#include <QSettings>
#include <QList>
#include <QDataStream>
#include <QVariant>
#include <QVariantList>
#include <QDebug>
#include <deque>
template <class T> static QVariant toVariant(const QList<T> &list)
{
QVariantList variantList;
variantList.reserve(list.size());
for (const auto& v : list)
{
variantList.append(v);
}
return variantList;
}
template <class T> static QList<T> toList(const QVariant &qv)
{
QList <T> dataList;
foreach(QVariant v, qv.value<QVariantList>()) {
dataList << v.value<T>();
}
return dataList;
}
void Gen()
{
QList<QString> data {"hello", "world","how", "are", "you"};
QList<int> ages {10,20,30,40};
QSettings setup("stuff.ini", QSettings::IniFormat);
setup.beginWriteArray("rules");
for (int groups=0;groups<3;groups++)
{
setup.setArrayIndex(groups);
setup.setValue("rule",QString("Rule-%1").arg(groups));
setup.setValue("data", toVariant (data));
setup.setValue("ages", toVariant (ages));
}
setup.endArray();
setup.sync();
}
void Read()
{
QSettings setupR("stuff.ini", QSettings::IniFormat);
int rule_count = setupR.beginReadArray("rules");
for (int groups=0;groups<rule_count;groups++)
{
setupR.setArrayIndex(groups);
QString nameRead = setupR.value("rule").toString();
QList<QString> dataRead = toList<QString>(setupR.value("data"));
qDebug() << "Rule " << groups;
qDebug() << "Rule Read" << nameRead;
qDebug() << "Data Read2" << dataRead;
}
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
// Write
Gen();
// Read
Read();
exit(0);
//return a.exec();
}
You should end up with an INI file which looks like this ...
[rules]
1\ages=10, 20, 30, 40
1\data=hello, world, how, are, you
1\rule=Rule-0
2\ages=10, 20, 30, 40
2\data=hello, world, how, are, you
2\rule=Rule-1
3\ages=10, 20, 30, 40
3\data=hello, world, how, are, you
3\rule=Rule-2
size=3
The nice thing here is you can edit this outside of QT (Just be careful) ...

Resources