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

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

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: QTreeView + QFileSystemModel - удаление папки/файла  (Прочитано 11572 раз)
Serega
Самовар
**
Offline Offline

Сообщений: 127


Просмотр профиля
« : Март 26, 2015, 04:33 »

В продолжение темы (там вложен работающий исходник Модель/Представление) http://www.prog.org.ru/topic_28603_0.html

Код
C++ (Qt)
void MainWindow::contextMenuDelete()
{
   QModelIndex index = ui.treeView->currentIndex();
   if(!index.isValid())
       return;
   if(dirmodel->fileInfo(index).isDir())
   {
       dirmodel->rmdir(index);
//            dirmodel->remove(index);
   }
   else if( dirmodel->fileInfo(index).isFile() )
 
       dirmodel->remove(index);
 
       if( dirmodel->fileInfo(ui.treeView->indexBelow(index)).isFile() )
       {
           index = ui.treeView->indexBelow(index);
       }
       else
       {
           index = ui.treeView->indexAbove(index);
       }
}

Если удалять пустую папку, все в порядке, удаляется как положенно.
Если пользователь попытается удалить папку, содержащую другую папку, как и положенно папка не может быть удалена.
Но после такой попытки проблема такого плана: вложенная папка удаляется (если пуста), однако пункт остается видим в treeView. Если после этого удалить родителя, то родительская и вложенная папки исчезнут.
Наверное можно решить проблему путем предварительной проверки на пустоту папки, но что то как то не соображу по поводу метода проверки?
Возможно информации немного, но может кто сталкивался с такой проблемой и поделится вариантом решения?
Если удалить через индекс модели (закомментированно), удаляет, но и все вложенное содержимое, что не безопасно для пользователя.

С удалением файлов все впорядке. Но есть маленький недостаток при удалении файла на мгновение видно расширение файла. Как то возможно это поправить?

Записан
Serega
Самовар
**
Offline Offline

Сообщений: 127


Просмотр профиля
« Ответ #1 : Март 27, 2015, 05:46 »

Однако придется лепить проверку.
К сожалению и здесь не все гладко. Можно сориентироваться посчитав количество строк у родителя. Так работает:
Код
C++ (Qt)
   if(dirmodel->fileInfo(index).isDir())
   {
//        if(!dirmodel->hasChildren(index))
       if(!dirmodel->rowCount(index))
           dirmodel->rmdir(index);
   }

А вот этот метод:
Код:
if(!dirmodel->hasChildren(index))
При любых обстоятельствах дает true и если папка пуста в том числе.
Может кто в курсе, что может быть не так?
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3257


Просмотр профиля
« Ответ #2 : Март 27, 2015, 09:54 »

Однако придется лепить проверку.
К сожалению и здесь не все гладко. Можно сориентироваться посчитав количество строк у родителя. Так работает:
Код
C++ (Qt)
   if(dirmodel->fileInfo(index).isDir())
   {
//        if(!dirmodel->hasChildren(index))
       if(!dirmodel->rowCount(index))
           dirmodel->rmdir(index);
   }

А вот этот метод:
Код:
if(!dirmodel->hasChildren(index))
При любых обстоятельствах дает true и если папка пуста в том числе.
Может кто в курсе, что может быть не так?

Всё так, этот метод нужен для того, чтобы вью могла понять - нужно рисовать плюсик около "папки" или не надо. Во всех ФМ плюсик рисуется всегда, даже если папка пуста, потому и такое поведение. Чтобы узнать, есть ли элементы в папке, используйте rowCount()
Записан
Serega
Самовар
**
Offline Offline

Сообщений: 127


Просмотр профиля
« Ответ #3 : Март 27, 2015, 19:20 »

Однако в описании метода ясно сказано как он должен работать и об узкой направленности ничего не сказанно. Тут что то другое. Но наверное сам должен разобраться где напартачил. Не хотелось бы пользоваться более медленным методом.
К тому же показ галочек так же надо будет отладить.
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3257


Просмотр профиля
« Ответ #4 : Март 30, 2015, 12:34 »

Однако в описании метода ясно сказано как он должен работать и об узкой направленности ничего не сказанно. Тут что то другое. Но наверное сам должен разобраться где напартачил. Не хотелось бы пользоваться более медленным методом.
К тому же показ галочек так же надо будет отладить.

Вы не поверите:
Код:
bool QAbstractItemModel::hasChildren(const QModelIndex &parent) const
{
    return (rowCount(parent) > 0) && (columnCount(parent) > 0);
}
Записан
Serega
Самовар
**
Offline Offline

Сообщений: 127


Просмотр профиля
« Ответ #5 : Март 30, 2015, 14:39 »

Авварон
Спасибо за ясный ответ Улыбающийся. Действительно небыло смысла заморачиваться.
Записан
Serega
Самовар
**
Offline Offline

Сообщений: 127


Просмотр профиля
« Ответ #6 : Март 30, 2015, 18:06 »

Еще одна маленькая неувязка.
Метод rowCount(index) не считает строки если папка ни разу не была открыта.
С чем это может быть связанно и как поправить?
Записан
kai666_73
Крякер
****
Offline Offline

Сообщений: 319


Просмотр профиля
« Ответ #7 : Март 30, 2015, 18:37 »

Еще одна маленькая неувязка.
Метод rowCount(index) не считает строки если папка ни разу не была открыта.
С чем это может быть связанно и как поправить?

Гляди в сторону
Код
C++ (Qt)
bool QAbstractItemModel::canFetchMore(const QModelIndex & parent) const
void QAbstractItemModel::fetchMore(const QModelIndex & parent)
 
Записан
Serega
Самовар
**
Offline Offline

Сообщений: 127


Просмотр профиля
« Ответ #8 : Апрель 01, 2015, 13:30 »

Спасибо за помощь!

Но поступил попроще. Покритикуйте:
Код
C++ (Qt)
   if( !managerModel->rowCount( index ) )
   {
     managerModel->rmdir( index );
   }
   if( QDir( managerModel->filePath( index ) ).exists() )
   {
     m_managerView->expand( index );
     QMessageBox* pmbx =
         new QMessageBox( QMessageBox::Warning,
                         "Manager",
                         "Directory is not empty!",
                         QMessageBox::Cancel );
     pmbx->exec();
     delete pmbx;
   }

Попутно, можно ли вместо m_managerView->expand( index ); как то расскрыть всю ветку простым способом?
Записан
Serega
Самовар
**
Offline Offline

Сообщений: 127


Просмотр профиля
« Ответ #9 : Апрель 06, 2015, 21:25 »

Поскольку здесь разобрались http://www.prog.org.ru/topic_28726_0.html Может теперь лучше использовать метод hasChildren?
Записан
Serega
Самовар
**
Offline Offline

Сообщений: 127


Просмотр профиля
« Ответ #10 : Апрель 07, 2015, 05:30 »

Итак если переопределяем метод:
Код
C++ (Qt)
bool managerModel::hasChildren( const QModelIndex & parent ) const
{
 return QDir(filePath(parent)).count() > 2;
}

То удаление папок дерева выглядит подобным образом:
Код
C++ (Qt)
 if( m_managerModel->hasChildren(index) )
   {
     m_managerView->expand(index);
     QMessageBox* pmbx =
         new QMessageBox(QMessageBox::Warning,
                         tr( "Content Manager" ),
                         tr( "Directory is not empty!" ),
                         QMessageBox::Cancel);
     pmbx->exec();
     delete pmbx;
   }
   else
   {
     m_managerModel->rmdir(index);
   }  

Аккуратнее?  Эффективнее ли? Во всяком случае не короче, но как то с технической точки зрения правильнее.
Записан
gil9red
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 1805



Просмотр профиля WWW
« Ответ #11 : Апрель 07, 2015, 06:44 »


То удаление папок дерева выглядит подобным образом:
Код
C++ (Qt)
 if( m_managerModel->hasChildren(index) )
   {
     m_managerView->expand(index);
     QMessageBox* pmbx =
         new QMessageBox(QMessageBox::Warning,
                         tr( "Content Manager" ),
                         tr( "Directory is not empty!" ),
                         QMessageBox::Cancel);
     pmbx->exec();
     delete pmbx;
   }
   else
   {
     m_managerModel->rmdir(index);
   }  

Аккуратнее?  Эффективнее ли? Во всяком случае не короче, но как то с технической точки зрения правильнее.

Можно же короче сделать:
Код
C++ (Qt)
     QMessageBox::warning(0, tr( "Content Manager" ), tr( "Directory is not empty!" ), QMessageBox::Cancel);
 

И не нужно будет выделять память в куче, а после освобождать Улыбающийся
« Последнее редактирование: Апрель 07, 2015, 06:54 от gil9red » Записан

Fregloin
Супер
******
Offline Offline

Сообщений: 1025


Просмотр профиля
« Ответ #12 : Апрель 07, 2015, 09:16 »

Не читал ваши темы но не кажется ли что проще все объеденить в одну тему нежели плодить одно и тоже 4 раза?
Записан
Serega
Самовар
**
Offline Offline

Сообщений: 127


Просмотр профиля
« Ответ #13 : Апрель 07, 2015, 11:27 »

gil9red спасибо! Я ведь только учусь  Улыбающийся. Год крапел над учебниками и видео по С/С++ до тех пар пока не осталось недопонимания при объяснении учебного материала, что бы изнутри осознать процессы и начать правильно читать чужой код/примеры/советы... До этого год кодил, но осозновал поверхностно. QT подтягиваю по мере работы. Практики практически нет. Оптимально писать код с ходу не могу. Да и все таки осталось еще не мало белых пятен которые пройдут только с практикой.
За советы спасибо. Значит пишем так:
Код
C++ (Qt)
 if(m_managerModel->fileInfo(index).isDir())
 {
   if( m_managerModel->hasChildren(index) )
   {
     m_managerView->expand(index);
     QMessageBox::warning(0, tr( "Content Manager" ), tr( "Directory is not empty!" ), QMessageBox::Cancel);
   }
   else
   {
     m_managerModel->rmdir(index);
   }
 }
Записан
Serega
Самовар
**
Offline Offline

Сообщений: 127


Просмотр профиля
« Ответ #14 : Апрель 07, 2015, 11:32 »

Не читал ваши темы но не кажется ли что проще все объеденить в одну тему нежели плодить одно и тоже 4 раза?
Вы не внимательны я наплодил уже 6 раз...
Однако все сабжики разные и темы четко определены, что не противоречит ни правилам хорошего тона, ни правилам форума...
С тем же успехом можно предложить объединить все топики в заголовке которых выявлены слова QTreeView и QFileSystemModel.

P.S. Не обещаю, но возможно когда нибудь я выложу в отдельный топик исходник менеджера для обсуждения, что бы вслушать критику его качества и произвести оптимизацию. Довольно не плохо получилось обойтись определением всего парой классов и получить то, что обычно требовало 3-4 класса. Обсуждаемые вопросы задавались не раз на просторах интернета, ответов найдено мало, если вообще найдены и весьма расплывчаты, требующие наращивать код и разбираться с документацией, некоторые решения оригинальны, хоть и тривиальны. Этот же код вышел на вид прост для новичков вроде меня как учебное пособие. При этом функционал не хуже, а код умещается в заветные 500 строк. Воткнуть его можно в любой проект.
« Последнее редактирование: Апрель 07, 2015, 11:53 от Serega » Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


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