Просмотр содержимого директории с помощью QDir


При помощи класса QDir можно получить содержимое указанной директории. При этом допускается применять различные фильтры, чтобы исключить из списка не интересующие вас файлы. Для этих целей в классе определены методы entryList() и entryInfoList(). Первый возвращает список имен элементов (QStringList), а второй — информационный список (QFileInfoList). Если вам нужно узнать только количество элементов, находящихся в директории, то просто вызовите метод count().

Программа, показанная на рисунке, осуществляет рекурсивный поиск файлов в директории, указанной в текстовом поле Directory (Директория). Нажатие кнопки с растровым изображением откроет диалоговое окно выбора нужной директории. В текстовом поле Mask (Маска) задается фильтр для отображаемых файлов. Например, для отображения исходных файлов на языке C++ нужно задать в поле Mask (Маска) *.срр и *.h. После нажатия кнопки Find (Поиск) производится отображение файлов, в соответствии с заданными параметрами. Результаты отображаются в виджете многострочного текстового поля.

{рисунок}


FileFinder::FileFinder(QWidget* pwgt/*= 0*/) : QWidget(pwgt) 
{
    m_ptxtDir    = new QLineEdit(QDir::current().absolutePath());
    m_ptxtMask   = new QLineEdit("*.cpp *.h");
    m_ptxtResult = new QTextEdit;

    QLabel*      plblDir  = new QLabel("&Directory");
    QLabel*      plblMask = new QLabel("&Mask");
    QPushButton* pcmdDir  = new QPushButton(QPixmap(fileopen), "");
    QPushButton* pcmdFind = new QPushButton("&Find");

    connect(pcmdDir, SIGNAL(clicked()), SLOT(slotBrowse()));
    connect(pcmdFind, SIGNAL(clicked()), SLOT(slotFind()));

    plblDir->setBuddy(m_ptxtDir);
    plblMask->setBuddy(m_ptxtMask);

    //Layout setup
    QGridLayout* pgrdLayout = new QGridLayout;
    pgrdLayout->setMargin(5);
    pgrdLayout->setSpacing(15);
    pgrdLayout->addWidget(plblDir, 0, 0);
    pgrdLayout->addWidget(plblMask, 1, 0);
    pgrdLayout->addWidget(m_ptxtDir, 0, 1);
    pgrdLayout->addWidget(m_ptxtMask, 1, 1);
    pgrdLayout->addWidget(pcmdDir, 0, 2);
    pgrdLayout->addWidget(pcmdFind, 1, 2);
    pgrdLayout->addWidget(m_ptxtResult, 2, 0, 1, 3);
    setLayout(pgrdLayout);
}

В конструкторе класса FileFinder создаются виджеты однострочного и многострочного текстовых полей (указатели m_ptxtDir, m_ptxtMask и m_ptxtResult). Первый виджет инициализируется абсолютным путем, возвращаемым методом QDir::absolutePath(), который, в свою очередь, инициализируется значением текущей директории, возвращаемой методом QDir::current() . Второй виджет инициализируется строкой, предназначенной для фильтрации найденных файлов. Для старта операции поиска и открытия диалогового окна выбора директории создаются две кнопки нажатия— указатели pcmdFind и pcmdDir, которые соединяются со слотами slotFind() и slotBrowse(). В конструкторе создаются два виджета надписей, а с помощью метода setBuddy() они ассоциируются с виджетами однострочных текстовых полей. Созданные виджеты размещаются в виде таблицы при помощи объекта класса QGridLayout.


void FileFinder::slotBrowse()
{
    QString str = QFileDialog::getExistingDirectory
                  (
                    0, 
                    "Select a Directory", 
                    m_ptxtDir->text()
                  );

    if (!str.isEmpty()) {
        m_ptxtDir->setText(str);
    }
}

Метод slotBrowse(), который открывает диалоговое окно для выбора директории поиска. После закрытия этого окна директория записывается в текстовое поле Directory (Директория) с помощью метода setText().


void FileFinder::slotFind()
{
    start(QDir(m_ptxtDir->text()));
}

Метод slotFind() запускает операцию поиска и передает в метод start() выбранную пользователем директорию.


void FileFinder::start(const QDir& dir)
{
    QApplication::processEvents();

    QStringList listFiles = 
        dir.entryList(m_ptxtMask->text().split(" "), QDir::Files);
    
    foreach (QString file, listFiles) {
        m_ptxtResult->append(dir.absoluteFilePath(file));
    }

    QStringList listDir = dir.entryList(QDir::Dirs);
    foreach (QString subdir, listDir) {
        if (subdir == "." || subdir == "..") {
            continue;
        }
        start(QDir(dir.absoluteFilePath(subdir)));
    }
}

Процесс поиска заданных файлов может быть длительным, что может привести к "замиранию" графического интерфейса программы. Поэтому, для подавления этого нежелательного эффекта, при каждом вызове метода воспользуемся методом QApplication::processEvent() и дадим возможность обработаться накопившимся событиям. В методе start о переменная listFiles получает список файлов текущей директории. Для этого в методе установлены два параметра. Первый представляет собой список шаблонов поиска, которые распространяются на имена и расширения файлов. В нашем случае мы преобразуем строку в список, разделив ее посредством пробелов, с помощью QString::split(). Второй параметр (QDir::Files) указывает на то, что список должен содержать только файлы. Элементы полученного списка добавляются в виджет многострочного текстового поля с помощью метода append(). По завершению работы цикла добавления, в метод entryList() передается параметр QDir::Dirs для получения списка директорий. Для каждого из элементов списка, кроме "." и "..", вызывается метод start().

Читать далее: Информация о файлах. Класс QFileInfo