QDir::setCurrent vs QFileInfo:: - c++

I've come across a anomaly in Qt (v4.8.4) when re-assigning a new path to a pre-existing QDir object. Here is a reduced example demonstrating this:
QString path1("F:/"); //Path must exist...
QString path2("F:/Some/Valid/Path/For/You/"); //Path must exist...
//Set default...
QFileInfo fi1(path1);
QDir d(fi1.absoluteDir());
//CASE 1...
if(!d.setCurrent(path2)) {
qDebug() << QString("Cannot set path (%1)").arg(path2).toAscii().data();
return -1;
}
qDebug() << "CASE 1:";
qDebug() << QString("path2: %1").arg(path2).toAscii().data();
qDebug() << QString("d : %1").arg(d.absolutePath()).toAscii().data();
//END of CASE 1...
//CASE 2...
QFileInfo fi2(path2);
d = fi2.absoluteDir();
qDebug() << "CASE 2:";
qDebug() << QString("path2: %1").arg(path2).toAscii().data();
qDebug() << QString("d : %1").arg(d.absolutePath()).toAscii().data();
//END of CASE 2...
Even though the call to d.setCurrent(path2) returns true, the new path is not set in the QDir object. OTOH, assigning the new path 1st to a QFileInfo object, and then calling absoluteDir() on that object returns an updated QDir object.
You can then directly assign the returned object to a pre-existing QDir object (through the overridden assignment operator), and the path in the QDir object will be correctly updated.
Why does the CASE 1 not work?

QDir::setCurrent is a static function that sets the current path of the application. It doesn't modifiy any QDir instance.
You should use QDir::setPath to assign a new path (or assign the QString directly to QDir with the = operator, since the conversion is implicit).

Related

How to make a list(QList) of QFiles? and how it works?

I am trying to make a list of QFiles, I went for the QList approach but am not sure if it is good approach or not.
I write this code but it fails to build!
QList<QFile> filesList;
QFile file_1(QString("path/to/file_1"));
QFile file_2(QString("path/to/file_2"));
filesList.append(file_1);
filesList.append(file_2);
for(auto& file : filesList){
if(!file.open(QIODevice::ReadOnly)){
qDebug() << "file is not open.";
}
}
The build failed with this error:
error: ‘QFile::QFile(const QFile&)’ is private within this context
if (QTypeInfo<T>::isLarge || QTypeInfo<T>::isStatic) n->v = new T(t);
^~~~~~~~
Is it good to use QList approach of making a list of files to use later? if so, how to fix my code ?
It looks like the issue is that the QFile class has a private copy constructor, which means that it cannot be copied. Therefore, it cannot be stored in a container like QList. One way to work around this issue is to store pointers to QFile objects in the QList instead of the objects themselves.
Try this:
QList<QFile*> filesList;
QFile* file_1 = new QFile(QString("path/to/file_1"));
QFile* file_2 = new QFile(QString("path/to/file_2"));
filesList.append(file_1);
filesList.append(file_2);
for(auto file : filesList){
if(!file->open(QIODevice::ReadOnly)){
qDebug() << "file is not open.";
}
}
Updated version:
QList<QFile> filesList;
QFile file_1("path/to/file_1");
QFile file_2("path/to/file_2");
filesList.append(file_1);
filesList.append(file_2);
for(auto& file : filesList){
if(!file.open(QIODevice::ReadOnly)){
qDebug() << "file is not open.";
}
}
thanks to #Fareanor comment, I solved this by making a list of QString for the paths and I used QFile when I open the file:
QList<QString> filesList;
filesList.append("path/to/file_1");
filesList.append("path/to/file_2");
for(auto& path : filesList){
QFile file(path);
if(!file.open(QIODevice::ReadOnly)){
qDebug() << "file is not open.";
}
}
If you want the QList of QFile, why not emplacing the elements?. No need for creating them outside and copying them in when they can be created in-place:
QList<QFile> filesList;
filesList.emplaceBack(QString("path/to/file_1"));
filesList.emplaceBack(QString("path/to/file_2"));
for(auto& file : filesList){
if(!file.open(QIODevice::ReadOnly)){
qDebug() << "file is not open.";
}
}

Qt: empty content of opened QFile for a .txt file from the project resources

I tried this in my project in mainwindow.cpp:
QString dir = ":/nodesDir/nodesDir/";
QFile baseFile(dir + "allNodeNames.txt");
qDebug() << baseFile.exists(); // true
qDebug() << baseFile.readAll(); // ""
but it is wrong, the content of the file is
plusOperator
Why does it say, that there would be nothing written in the file? Or What did I miss in my code?`
Thanks for answers!
In order to read the file you need to open it for it we use open () and we indicate the way we want it to open. We must also bear in mind that the files stored in the resources are read only, so they can not be modified.
QString dir = ":/nodesDir/nodesDir/";
QFile baseFile(dir + "allNodeNames.txt");
qDebug() << baseFile.exists(); // true
qDebug()<< baseFile.open(QFile::ReadOnly);
qDebug() << baseFile.readAll(); // ""
Output:
true
true
"plusOperator"

Changing current path of a Qt Application

I am using Qt Library and I want to set the current path to the path contained in a QString oldConfigFileName and i am using setCurrent() but setCurrent is returning a false value indicating a failure in changing path.
Code:
QString path = QDir::currentPath();
std::string currentpath = path.toStdString();
std::string configPath = oldConfigFileName.toStdString();
bool res = QDir::setCurrent(oldConfigFileName);
if(res)
{
qDebug() << "Path Changed";
}
else
{
qDebug() << "Path not changed";
}
The problem is the path you are using is a full path to a config file containing the file name. When you try to change the directory to this path the command will fail because oldConfigFileName is a file not an existing folder. A simple way to fix this is to use QFileInfo to remove the filename part from the path then use that as the directory.
QFileInfo fi(oldConfigFileName);
bool res = QDir::setCurrent(fi.path());
if(res)
{
qDebug() << "Path Changed";
}
else
{
qDebug() << "Path not changed";
}
Without knowing an actual content of the oldConfigFileName, one reason for failure may be that the path does not exists. It may be good idea to check existance of the path before calling the QDir::setCurrent() -method.
if(!QDir(oldConfigFileName).exists())
{
qDebug() << "Path does not exists.";
// Path does not exists, if needed, it can be created by
// QDir().mkdir(oldConfigFileName);
}
Another reason for the failure may be that oldConfigFileName does not contain valid path string. To check that, I would change debug logs following way:
if(res)
{
qDebug() << "Path Changed";
}
else
{
qDebug() << "Path not changed. Path string = " << oldConfigFileName;
}

QSetting trouble

I am working with QSettings function. Once successfully set in the .h file variable
QSettings *settings;
inside the constructor (cpp. file) I set the variable in this way, to obtain a path like Draw/Input/Cells/Width
settings = new QSettings("MySoft", "Star Runner");
settings->beginGroup("Draw");
settings->beginGroup("Input");
settings->beginGroup("Cells");
settings->setValue("width", 80);
settings->endGroup();
settings->endGroup();
settings->endGroup();
The problem is that width value is properly set to 80 only if during the declaration of the organization name is set to "MySoft": if you assign any other value (e.g. "foobar"), doing a test via
qDebug() << settings->value("width", "").toString();
the width key as no value
You should also start and end the groups when reading the value. So you could either try
qDebug() << settings->value("Draw/Input/Cells/width", "").toString();
or
settings->beginGroup("Draw");
settings->beginGroup("Input");
settings->beginGroup("Cells");
qDebug() << settings->value("width", "").toString();
settings->endGroup();
settings->endGroup();
settings->endGroup();

Display QList contents

I want to display the contents of a QList just like how it is displayed in the console with qDebug()
For example:
QList<QNetworkCookie> cookies = mManager->cookieJar()->cookiesForUrl(mUrl);
qDebug() << "COOKIES for" << mUrl.host() << cookies;
Output:
QNetworkCookie("MSession=kr6i819jbvkorherbe76oh23c7; domain=website.com; path=/)"
Is there a function that I can use?
You can create a QDebug object that will store anything streamed into it, inside a string. Here is it:
QString str;
QDebug dStream(&str);
dStream << mUrl.host();
Now you can put str wherever you want. For example a QTextBrowser:
ui->textBrowser->insertPlainText(str);
This should work everywhere that qDebug() works. Because qDebug() itself returns a QDebug object according to this documentation.