Russian Qt Forum

Qt => Общие вопросы => Тема начата: QuAzI от Декабрь 14, 2010, 04:02



Название: QFileInfoList пуст при вызове из другой Qt-программы
Отправлено: QuAzI от Декабрь 14, 2010, 04:02
Есть консольная программа, ищущая рекурсивно файлы по маске. Долго не мог понять, почему при вызове из другой программы ничего не находится. В итоге стал писать данные в файл и нашёл проблемную процедуру
Код:
int ScanDir(QDir *directory, QString filemask, QSqlQuery *query)
{
    QDir dir(directory->absolutePath());
    dir.setFilter( QDir::Files | QDir::Readable | QDir::AllDirs | QDir::NoDotAndDotDot );
    QFileInfoList list = dir.entryInfoList(QDir::nameFiltersFromString(filemask));
        for (int i=0; i<(list.count());i++)
        {
            if (list.at(i).isFile())
            {
              ScanFile(list.at(i).absoluteFilePath(), query);
            }
             else
            {
            QDir new_path(list.at(i).absoluteFilePath());
            ScanDir(&new_path, filemask, query);
            }
        }
return 0;
}
Почему-то при запуске ручками из консоли с теми же параметрами, либо при запуске из компилятора, QFileInfoList заполнен и работает. Но если программу запускать из другой Qt-программы (GUI-обёртка к ней), то QFileInfoList пуст, а QFileInfoList->count() возвращает 0.
Как бы эту глюку красиво обойти?


Название: Re: QFileInfoList пуст при вызове из другой Qt-программы
Отправлено: Пантер от Декабрь 14, 2010, 08:23
Мрак. Ты уверен, что эта фукнция написана правильно? QDir *directory как изначально задаешь?


Название: Re: QFileInfoList пуст при вызове из другой Qt-программы
Отправлено: QuAzI от Декабрь 14, 2010, 08:50
Вызывается эта функция так
Код:
      QSqlQuery query;
[... код создания таблиц...]

      QString filemask;
      filemask = argv[1];
      QDir dir(argv[param_index]);
      dir.setPath(dir.absolutePath());     
      if (dir.exists())
      {         
          // Сканируем указанную директорию, учитывая маску
          ScanDir(&dir, filemask, &query);
      }
Вроде должно было бы падать, если б не так задавал. Или хотябы материться (благо в Qt на эту тему неплохо). Собирал на винде и FreeBSD. "*.o" и прочие временные файлы при переносе сносил, да и при сборке пару раз, чтобы быть уверенным что старый мусор не цепляется.


Название: Re: QFileInfoList пуст при вызове из другой Qt-программы
Отправлено: Пантер от Декабрь 14, 2010, 09:56
QuAzI, советую тебе засесть за теорию. И начать с с++.
Зачем dir.setPath после того, как ты этот путь передаешь в конструктор???
Косяк в том, что когда ты запускаешь прогу без параметров, argv[param_index] скорее всего пусто (что такое param_index по коду непонятно). QDir на это не ругается, но в сканирование ты не попадаешь.


Название: Re: QFileInfoList пуст при вызове из другой Qt-программы
Отправлено: QuAzI от Декабрь 14, 2010, 10:37
Прога не запускается без параметров. Там стоит проверка что argc>2
Прога работает при запуске из консоли. При запуске из другого Qt-проекта не работает.
Обновляю путь до абсолютного чтобы потом работать с полными путями, а не относительными, т.к. программу могли стартануть и с относительным путём, приходится менять. Так же эти полные пути сохраняются потом в базу.
В саму функцию директория и маска передаются нормально. Специально вставлял запись в файл и отслеживал, на каком участке какие значения имею.


Название: Re: QFileInfoList пуст при вызове из другой Qt-программы
Отправлено: QuAzI от Декабрь 14, 2010, 10:43
Полный исходник в аттаче


Название: Re: QFileInfoList пуст при вызове из другой Qt-программы
Отправлено: Пантер от Декабрь 14, 2010, 10:50
Как запускаешь из другого Qt-проекта?


Название: Re: QFileInfoList пуст при вызове из другой Qt-программы
Отправлено: QuAzI от Декабрь 14, 2010, 11:06
Код:
    QString dir(QFileDialog::getExistingDirectory(this, tr("Select Directory"), HomeDir.absolutePath(), QFileDialog::ShowDirsOnly));
    if (!dir.isEmpty())
    {
    QProcess *proc = new QProcess();
    QString findproc("./find2db");
    QStringList findparam;
    QString mask("\"*\"");
    findparam << mask << dir;   
    proc->start(findproc, findparam);
    }


Название: Re: QFileInfoList пуст при вызове из другой Qt-программы
Отправлено: QuAzI от Декабрь 14, 2010, 15:30
Как-то оно никак маску обрабатывает. Если задано "*" или "*.c" то из приложения не работает (если из консоли запустить с теми же параметрами - работает). Если прописать вместо маски имя файла (нужно обработать всего один файл), то оно работает.


Название: Re: QFileInfoList пуст при вызове из другой Qt-программы
Отправлено: BRE от Декабрь 14, 2010, 15:40
Как-то оно никак маску обрабатывает. Если задано "*" или "*.c" то из приложения не работает (если из консоли запустить с теми же параметрами - работает). Если прописать вместо маски имя файла (нужно обработать всего один файл), то оно работает.
Попробуй так запускать:
Код
C++ (Qt)
QString dir(QFileDialog::getExistingDirectory(this, tr("Select Directory"), HomeDir.absolutePath(), QFileDialog::ShowDirsOnly));
   if (!dir.isEmpty())
   {
   QProcess *proc = new QProcess();
   QString findproc("sh");
   QStringList findparam;
   QString mask("\"*\"");
   findparam << "./find2db" << mask << dir;    
   proc->start(findproc, findparam);
   }
 


Название: Re: QFileInfoList пуст при вызове из другой Qt-программы
Отправлено: Пантер от Декабрь 14, 2010, 15:41
В консоли * обрабатывается по своему. Попробуй в консоли запустить так:
prog "\*" /some/path


Название: Re: QFileInfoList пуст при вызове из другой Qt-программы
Отправлено: BRE от Декабрь 14, 2010, 15:44
Точнее смылс в том, что все эти маски обрабатывает шелл.
Попробуй сделать шелл-скрипт из которого и вызывай find2db.




Название: Re: QFileInfoList пуст при вызове из другой Qt-программы
Отправлено: Пантер от Декабрь 14, 2010, 15:49
Кстати, а откуда ты взял QDir::nameFiltersFromString?


Название: Re: QFileInfoList пуст при вызове из другой Qt-программы
Отправлено: QuAzI от Декабрь 14, 2010, 17:07
BRE, да, как-то не уследил. Оказалось что при запуске в консоль всё равно вместо "\*.\*" попадает *.* который в свою очередь интерпретируется бинарником собранным под Qt как перечень всех файлов в текущей директории.
Проверить просто
Код:
#include <QtCore/QCoreApplication>
#include <QDebug>

int main(int argc, char *argv[])
{   
    QCoreApplication a(argc, argv);
    qDebug() << argv[0] << argv[1] << argv[2];
    return a.exec();
}
Запущать этот пример с маской * или *.*
Шеллскрипт тоже сделал, пишет в лог, с какие параметры ему скормили. Одного не понял. При запуске "./find2db" если есть exe-файл, он его запускает (не важно что расширение не указал явно). Но например find2db.bat не хочет, приходится жёстко в исходник забивать, что запускать.

Пантер, не помню, скорее всего нашёл с каким-либо из примеров. Суть приблуды - она список грузит из строки - в строке через пробел перечислены маски. Т.е. можно задать "*.c *.h *.pro" и он все три маски загрузит и отдаст как список.