Russian Qt Forum

Qt => Model-View (MV) => Тема начата: Serega от Март 26, 2015, 04:33



Название: QTreeView + QFileSystemModel - удаление папки/файла
Отправлено: Serega от Март 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. Если после этого удалить родителя, то родительская и вложенная папки исчезнут.
Наверное можно решить проблему путем предварительной проверки на пустоту папки, но что то как то не соображу по поводу метода проверки?
Возможно информации немного, но может кто сталкивался с такой проблемой и поделится вариантом решения?
Если удалить через индекс модели (закомментированно), удаляет, но и все вложенное содержимое, что не безопасно для пользователя.

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



Название: Re: QTreeView + QFileSystemModel - удаление папки/файла
Отправлено: Serega от Март 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 и если папка пуста в том числе.
Может кто в курсе, что может быть не так?


Название: Re: QTreeView + QFileSystemModel - удаление папки/файла
Отправлено: Авварон от Март 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()


Название: Re: QTreeView + QFileSystemModel - удаление папки/файла
Отправлено: Serega от Март 27, 2015, 19:20
Однако в описании метода ясно сказано как он должен работать и об узкой направленности ничего не сказанно. Тут что то другое. Но наверное сам должен разобраться где напартачил. Не хотелось бы пользоваться более медленным методом.
К тому же показ галочек так же надо будет отладить.


Название: Re: QTreeView + QFileSystemModel - удаление папки/файла
Отправлено: Авварон от Март 30, 2015, 12:34
Однако в описании метода ясно сказано как он должен работать и об узкой направленности ничего не сказанно. Тут что то другое. Но наверное сам должен разобраться где напартачил. Не хотелось бы пользоваться более медленным методом.
К тому же показ галочек так же надо будет отладить.

Вы не поверите:
Код:
bool QAbstractItemModel::hasChildren(const QModelIndex &parent) const
{
    return (rowCount(parent) > 0) && (columnCount(parent) > 0);
}


Название: Re: QTreeView + QFileSystemModel - удаление папки/файла
Отправлено: Serega от Март 30, 2015, 14:39
Авварон
Спасибо за ясный ответ :). Действительно небыло смысла заморачиваться.


Название: Re: QTreeView + QFileSystemModel - удаление папки/файла
Отправлено: Serega от Март 30, 2015, 18:06
Еще одна маленькая неувязка.
Метод rowCount(index) не считает строки если папка ни разу не была открыта.
С чем это может быть связанно и как поправить?


Название: Re: QTreeView + QFileSystemModel - удаление папки/файла
Отправлено: kai666_73 от Март 30, 2015, 18:37
Еще одна маленькая неувязка.
Метод rowCount(index) не считает строки если папка ни разу не была открыта.
С чем это может быть связанно и как поправить?

Гляди в сторону
Код
C++ (Qt)
bool QAbstractItemModel::canFetchMore(const QModelIndex & parent) const
void QAbstractItemModel::fetchMore(const QModelIndex & parent)
 


Название: Re: QTreeView + QFileSystemModel - удаление папки/файла
Отправлено: Serega от Апрель 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 ); как то расскрыть всю ветку простым способом?


Название: Re: QTreeView + QFileSystemModel - удаление папки/файла
Отправлено: Serega от Апрель 06, 2015, 21:25
Поскольку здесь разобрались http://www.prog.org.ru/topic_28726_0.html Может теперь лучше использовать метод hasChildren?


Название: Re: QTreeView + QFileSystemModel - удаление папки/файла
Отправлено: Serega от Апрель 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);
   }  

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


Название: Re: QTreeView + QFileSystemModel - удаление папки/файла
Отправлено: gil9red от Апрель 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);
 

И не нужно будет выделять память в куче, а после освобождать :)


Название: Re: QTreeView + QFileSystemModel - удаление папки/файла
Отправлено: Fregloin от Апрель 07, 2015, 09:16
Не читал ваши темы но не кажется ли что проще все объеденить в одну тему нежели плодить одно и тоже 4 раза?


Название: Re: QTreeView + QFileSystemModel - удаление папки/файла
Отправлено: Serega от Апрель 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);
   }
 }


Название: Re: QTreeView + QFileSystemModel - удаление папки/файла
Отправлено: Serega от Апрель 07, 2015, 11:32
Не читал ваши темы но не кажется ли что проще все объеденить в одну тему нежели плодить одно и тоже 4 раза?
Вы не внимательны я наплодил уже 6 раз...
Однако все сабжики разные и темы четко определены, что не противоречит ни правилам хорошего тона, ни правилам форума...
С тем же успехом можно предложить объединить все топики в заголовке которых выявлены слова QTreeView и QFileSystemModel.

P.S. Не обещаю, но возможно когда нибудь я выложу в отдельный топик исходник менеджера для обсуждения, что бы вслушать критику его качества и произвести оптимизацию. Довольно не плохо получилось обойтись определением всего парой классов и получить то, что обычно требовало 3-4 класса. Обсуждаемые вопросы задавались не раз на просторах интернета, ответов найдено мало, если вообще найдены и весьма расплывчаты, требующие наращивать код и разбираться с документацией, некоторые решения оригинальны, хоть и тривиальны. Этот же код вышел на вид прост для новичков вроде меня как учебное пособие. При этом функционал не хуже, а код умещается в заветные 500 строк. Воткнуть его можно в любой проект.


Название: Re: QTreeView + QFileSystemModel - удаление папки/файла
Отправлено: Igors от Апрель 07, 2015, 15:38
Воткнуть его можно в любой проект.
Удаление папки/мамки - опасная операция, можно грохнуть исходники проекта и хз насколько свежа последняя копия. Не случайно в ОС есть и undo и удаляется только в trash.

Желание разобраться - хорошо, но всегда надо думать "а кому это нужно?" или, по-простому "кто это купит". И начинающему лучше сразу задаваться этими вопросами.


Название: Re: QTreeView + QFileSystemModel - удаление папки/файла
Отправлено: Serega от Апрель 07, 2015, 16:10
Воткнуть его можно в любой проект.
Удаление папки/мамки - опасная операция, можно грохнуть исходники проекта и хз насколько свежа последняя копия. Не случайно в ОС есть и undo и удаляется только в trash.
Ну что то подобное было.
Но вроде как подстраховался. Это локальный менеджер за пределы которого пользователю не позволено выходить. Предназначен для создания каталога текстовых файлов, при нажатии на которые в другом окне появляется информация. Наверное что то вроде вивера. Но пользователь может определить любой каталог который и будет главным (локальным) хранилищем, за него запрещено выходить и само хранилище не может удалить, кроме как в штатном менеджере. Можно только менять расположение. Внутри же можно создавать и удалять папки/файлы. Причем может удалять только пустые папки и видит только текстовые файлы. Так что пользователь работает только с тем, что сам и создал в пределах менеджера. Кроме того, для текстовых файлов предполагается корзина и файлы не должны удаляться напрямую, а должны перемещаться в эту папку...
Так что вроде как изолировал и кое что предусмотрел.
Но если считаете, что может быть на столько серьезно постараюсь пересмотреть код и подумать, что можно было бы есче сделать в плане защиты.


Название: Re: QTreeView + QFileSystemModel - удаление папки/файла
Отправлено: Igors от Апрель 07, 2015, 16:53
Но если считаете, что может быть на столько серьезно постараюсь пересмотреть код и подумать, что можно было бы есче сделать в плане защиты.
Не считаю, просто в след раз постарайтесь выбрать более удачную "точку приложения" своих усилий. И "подсматривайте" (в хорошем смысле) что делают другие. Что-то типа "файловый менеджер" пишется сотнями, ну чего туда в кучу лезть?  :)


Название: Re: QTreeView + QFileSystemModel - удаление папки/файла
Отправлено: Serega от Апрель 07, 2015, 17:33
Прежде чем задавать вопросы конечно перерыл кучу информации. Не нашел то, что нужно мне. Вопросы которые задавал действительно были и не мало, а вот решения или советы уводили в такие дебри и не были конкретны. Вместо того что бы обойтись как оказалось парой строчек, предлагалось как миниму еще класс создать и переопределять кучу методов (ну куда мне крестьянину податься :))... Я ведь не изобретаю очердной нортон командер. Мне нужно было простое гибкое встраиваемое решение в другой более серьезный проект. В данном  случае коммерция меня не интересует, просто энтузиазм. Да и практика не плохая для меня.