Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to iterate through a QStringList

I'm trying to iterate through two different directories. The two directories are on the same root /.

void MainWindow::loadPlugins()
{
    pluginsDir = QDir(qApp -> applicationDirPath());

#if defined(Q_OS_WIN)
    if (pluginsDir.dirName().toLower() == "debug" || pluginsDir.dirName().toLower() == "release")
        pluginsDir.cdUp();
#elif defined(Q_OS_MAC)
    if (pluginsDir.dirName() == "MacOS") {
        pluginsDir.cdUp();
        pluginsDir.cdUp();
        pluginsDir.cdUp();
    }
#endif

    QStringList dirs;
    dirs << "plugins" << "core_plugs";

    QList<QObject *> loadedPlugs;

    for (int i = 0; i < dirs.size(); ++i)
    {
        cout << dirs.at(i).toLocal8Bit().constData() << endl;

        pluginsDir.cd(dirs.at(i).toLocal8Bit().constData());

        foreach (QString fileName, pluginsDir.entryList(QDir::Files)) {
            QPluginLoader loader(pluginsDir.absoluteFilePath(fileName));
            QObject *plugin = loader.instance();
            qDebug() << "NAME :: " << fileName;
            if (plugin && !(loadedPlugs . contains(plugin))) {
                loadedPlugs << plugin;
                dirs . removeAt(i);
            } else {
                continue;
            }
        }
    }
}

I'm only able to go into the first directory plugins in the list dirs << "plugins" << "core_plugs";. With a re-order dirs << "core_plugs" << "plugins";, the results are the same, and only the first directory, core_plugs is parsed.

Why am I getting this behavior, and how can I make it iterate through both directories.

UPDATE

void MainWindow::loadPlugins()
{
    pluginsDir = QDir(qApp -> applicationDirPath());

#if defined(Q_OS_WIN)
    if (pluginsDir.dirName().toLower() == "debug" || pluginsDir.dirName().toLower() == "release")
        pluginsDir.cdUp();
#elif defined(Q_OS_MAC)
    if (pluginsDir.dirName() == "MacOS") {
        pluginsDir.cdUp();
        pluginsDir.cdUp();
        pluginsDir.cdUp();
    }
#endif

    QStringList dirs;
    dirs << "plugins" << "core_plugs";

    QList<QObject *> loadedPlugs;

    for (int i = 0; i < dirs.size(); ++i)
    {
        pluginsDir.cd(dirs.at(i).toLocal8Bit().constData());

        foreach (QString fileName, pluginsDir.entryList(QDir::Files)) {
            QPluginLoader loader(pluginsDir.absoluteFilePath(fileName));
            QObject *plugin = loader.instance();
            if (plugin && !(loadedPlugs . contains(plugin))) {
                populateRevPlugins(plugin);
                loadedPlugs << plugin;
            }
        }
        qDebug() << pluginsDir . absolutePath();
        pluginsDir.cdUp();
        qDebug() << pluginsDir . absolutePath();
    }
}

Following Azeem's suggestion, I updated my attempt as shown above. I tried to cdUp(); after the foreach i.e:

foreach() {} pluginsDir.cdUp(); 

But, it doesn't get caught. It's too late there. Sooner than that and I get too few iterations. Could you please suggest how I can particularly go about it?

Thank you for the response!

like image 545
Program-Me-Rev Avatar asked Jun 15 '17 04:06

Program-Me-Rev


People also ask

How do I iterate over a QList?

If you want to iterate over a const QList, use QList::const_iterator instead. It is generally good practice to use QList::const_iterator on a non-const QList as well, unless you need to change the QList through the iterator. Const iterators are slightly faster, and can improve code readability.

What is a QStringList?

The QStringList class provides a list of strings. QStringList inherits from QList<QString>. Like QList, QStringList is implicitly shared. It provides fast index-based access as well as fast insertions and removals. Passing string lists as value parameters is both fast and safe.


1 Answers

Here is how you can iterate through a QStringList using C++11's range-based for loop:

const QStringList list { "A", "B", "C" };

for ( const auto& i : list  )
{
    qDebug() << i;
}

But, I believe that your problem is not the iteration. Your problem is that you are cding into a directory but not getting out of it i.e. cd("..") or cdUp().

As you said that both these directories are in the same path i.e. root /. So, after the processing in the nested loop, you need to get back to the root path to access the other directory.

You can simply check the result of the cd function whether it was successful or not. It is a Boolean function. But, in your case, the error handling is missing. With the error handling, it should be like this:

if ( dir.cd( path ) )
{
    // Do something here...
}

You don't have to get the dirs.at(i).toLocal8Bit().constData() for the cd function. It takes a QString.

Here is its signature:

bool QDir::cd( const QString& dirName );

Tip: You can also use QDirIterator for iterating a directory.


Below is a full working example.

I've followed this directory structure:

C:\Test
-- A
---- a.txt
-- B
---- b.txt

Code:

#include <QStringList>
#include <QDebug>
#include <QDir>
#include <cstdlib>

int main( void )
{
    const QString     root { "C:/Test" };
    const QStringList dirs { "A", "B" };

    QDir rootDir { root };
    qDebug() << "Root Path:" << rootDir.absolutePath();
    qDebug() << "Root List:" << rootDir.entryList( QDir::Dirs ) << '\n';

    for ( const auto& dir : dirs  )
    {
        if ( rootDir.cd( dir ) )
        {
            qDebug() << "Dir Path:" << rootDir.absolutePath();
            qDebug() << "Dir List:" << rootDir.entryList( QDir::Files ) << '\n';
        }

        rootDir.cdUp();
        qDebug() << "cding...";
        qDebug() << "Dir Path:" << rootDir.absolutePath() << '\n';
    }

    return EXIT_SUCCESS;
}

Output:

enter image description here

like image 176
Azeem Avatar answered Sep 22 '22 17:09

Azeem