Fornax-A
Fornax-A

Reputation: 1032

Multiple Levels submenus in Qt

I am trying to create a multiple level sub-menus in my Qt app. For this purpose, I am using a vector with directories' tree, example is:

C:\Users\meine\Main_menu_dir\folder_1\sub1
C:\Users\meine\Main_menu_dir\folder_1\sub2
C:\Users\meine\Main_menu_dir\folder_1\sub2\subsub1
C:\Users\meine\Main_menu_dir\folder_2\sub1
C:\Users\meine\Main_menu_dir\folder_2\sub1\subsub1
C:\Users\meine\Main_menu_dir\folder_2\sub2\subsub1
C:\Users\meine\Main_menu_dir\folder_2\sub2\subsub2

I am using boost lib as follow:

#include "boost/filesystem.hpp"
#include <iostream>
namespace fs = ::boost::filesystem;

I am using an iterator to go trough the string of names and create the submenu tree:

    for (// iter --> iterator in the list of files//)
    {
        if (fs::is_directory(*iter)) // from boost lib
        {
            QMenu *subMenu; // create a QMenu object
            // name --> name of the directory, i.e.: folder_1, sub1, sub2, .... 
            subMenu = new QMenu(QString::fromStdString(name), recursiveMenu);
            recursiveMenu->addMenu(subMenu); 
        }
    }   

in this way I create all the sub-menus under folder_1 (or, equivalently under Main_menu_dir depending from the starting point in the iterator). recursiveMenu is the menu at which I am appending the submenus. Maybe I should update it, something like:

recursiveMenu = subMenu;

How I can change the Menu structure to have the following menu levels:

 1. Folder_1
    1.1 sub1
    1.2 sub2
       1.2.1 subsub1
 2. Folder_2
    2.1 sub1
       2.1.1 subsub1
       2.1.2 subsub2
....

Thanks a lot.

Upvotes: 2

Views: 659

Answers (1)

eyllanesc
eyllanesc

Reputation: 243897

Using QDirIterator with QFileInfo:

#include <QtWidgets>

static void fill_menu(QMenu *menu, const QString & path, const QString & prefix={}){
    QDirIterator it(path, QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot);
    int number = 0;
    while (it.hasNext()) {
        number++;
        QString  newprefix = QString::number(number);
        if(!prefix.isEmpty())
            newprefix.prepend(prefix + ".");
        QFileInfo info(it.next());
        QString name = newprefix + " " + info.fileName();
        if(info.isDir()){
            QMenu *dirmenu = menu->addMenu(name);
            fill_menu(dirmenu, info.absoluteFilePath(), newprefix);
        }
        else if(info.isFile()){
            menu->addAction(name);
        }
    }
}

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QString directory{QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation)};
    QMainWindow w;
    QMenu menu{"Files"};
    w.menuBar()->addMenu(&menu);
    fill_menu(&menu, directory);
    w.show();
    return a.exec();
}

Upvotes: 3

Related Questions