Russian Qt Forum
Ноябрь 27, 2024, 02:33 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: QFileInfoList пуст при вызове из другой Qt-программы  (Прочитано 8648 раз)
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.
Как бы эту глюку красиво обойти?
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #1 : Декабрь 14, 2010, 08:23 »

Мрак. Ты уверен, что эта фукнция написана правильно? QDir *directory как изначально задаешь?
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
QuAzI
Гость
« Ответ #2 : Декабрь 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" и прочие временные файлы при переносе сносил, да и при сборке пару раз, чтобы быть уверенным что старый мусор не цепляется.
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #3 : Декабрь 14, 2010, 09:56 »

QuAzI, советую тебе засесть за теорию. И начать с с++.
Зачем dir.setPath после того, как ты этот путь передаешь в конструктор???
Косяк в том, что когда ты запускаешь прогу без параметров, argv[param_index] скорее всего пусто (что такое param_index по коду непонятно). QDir на это не ругается, но в сканирование ты не попадаешь.
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
QuAzI
Гость
« Ответ #4 : Декабрь 14, 2010, 10:37 »

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

Полный исходник в аттаче
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #6 : Декабрь 14, 2010, 10:50 »

Как запускаешь из другого Qt-проекта?
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
QuAzI
Гость
« Ответ #7 : Декабрь 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);
    }
Записан
QuAzI
Гость
« Ответ #8 : Декабрь 14, 2010, 15:30 »

Как-то оно никак маску обрабатывает. Если задано "*" или "*.c" то из приложения не работает (если из консоли запустить с теми же параметрами - работает). Если прописать вместо маски имя файла (нужно обработать всего один файл), то оно работает.
Записан
BRE
Гость
« Ответ #9 : Декабрь 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);
   }
 
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #10 : Декабрь 14, 2010, 15:41 »

В консоли * обрабатывается по своему. Попробуй в консоли запустить так:
prog "\*" /some/path
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
BRE
Гость
« Ответ #11 : Декабрь 14, 2010, 15:44 »

Точнее смылс в том, что все эти маски обрабатывает шелл.
Попробуй сделать шелл-скрипт из которого и вызывай find2db.


Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #12 : Декабрь 14, 2010, 15:49 »

Кстати, а откуда ты взял QDir::nameFiltersFromString?
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
QuAzI
Гость
« Ответ #13 : Декабрь 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" и он все три маски загрузит и отдаст как список.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.071 секунд. Запросов: 23.