Russian Qt Forum

Qt => Model-View (MV) => Тема начата: Serega от Март 15, 2015, 11:48



Название: QTreeView + QFileSystemModel - Drag and Drop
Отправлено: Serega от Март 15, 2015, 11:48
В продолжение тем:
QTreeView + QFileSystemModel - скрыть расширения файлов http://www.prog.org.ru/topic_28581_0.html
QTreeView + QFileSystemModel - чекбоксы http://www.prog.org.ru/topic_28586_0.html

Прикручиваем Drag and Drop
Код:
#include <QTreeView>

#include "MainWindow.h"
#include "ui_MainWindow.h"
#include "CFileSystemModel.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    QTreeView *treeView = new QTreeView();
    treeView->setModel(new CFileSystemModel);
    setCentralWidget(treeView);

// Настройка Drag and Drop
    //    Выбор режима выделения (множественный)
    treeView->setSelectionMode( QAbstractItemView::ExtendedSelection );

    treeView->setDragEnabled(true);
    treeView->setAcceptDrops(true);
    treeView->setDropIndicatorShown(true);

    //    Включаем режим перетаскивания (по умолчанию копирование)
    treeView->setDragDropMode( QAbstractItemView::InternalMove );

}

MainWindow::~MainWindow()
{
    delete ui;
}

Реализован режим перетаскивания файлов и папок с возможностью множественного выбора.

Пока не реализован режим копирования по Ctrl. Может кто подскажет легкий путь.
И немного не аккуратно - при опперации перетаскивания у файла на мгновение появляется расширение.

Сам код во вложении.


Название: Re: QTreeView + QFileSystemModel - Drag and Drop
Отправлено: Serega от Апрель 01, 2015, 13:47
Вышеописанным образом перетаскивание не работает в пределах одной паки (с папки в папку можно).
Как быть, где рыть?


Название: Re: QTreeView + QFileSystemModel - Drag and Drop
Отправлено: Serega от Апрель 02, 2015, 16:06
Таким нехитрым способом осуществил копирование с переносом по Ctrl:
Код
C++ (Qt)
void JournalManagerWidget::keyPressEvent(QKeyEvent *event)
{
 if(event->key() == Qt::Key_Control)
   m_managerView->setDragDropMode( QAbstractItemView::DragDrop );
}
 
void JournalManagerWidget::keyReleaseEvent(QKeyEvent *event)
{
 if(event->key() == Qt::Key_Control)
   m_managerView->setDragDropMode( QAbstractItemView::InternalMove );
}
С виду работает как положенно. Достаточна ли такая реализация?
Теории начитался и наслушался, вроде как не особо сложно разбираться. Но катастрофически мала практика кодинга. Поэтому страхуюсь вопросами. Что бы сразу исключить побочные проблемы. Ну допустим здесь следует дальше послать собитие.


По поводу вопроса выше на счет перетасквиния в пределах одной папки, т.е. сортировка пользователем. Если нет ответов, полагаю простых решений нет.
Но хотя бы решить такую проблему:
- Само дерево сортируется по алфавиту (папки вверху, файлы внизу). Метод setSortingEnabled ожидаемого результата не дает для меня, просто папки оказываются внизу.
- Однако это пол беды. При создании новой папки или файла, они определяются в конце дерева или текущей папки. Т.е. автосортировки не происходит.
- Если перетащить файл или папку, то происходит обновление дерева (автосортируется).
- Такое поведение создает хаос.
 Подскажите как избавиться? Сделать так, что бы дерево обновлялось при создании нового пунка.


Название: Re: QTreeView + QFileSystemModel - Drag and Drop
Отправлено: Serega от Апрель 03, 2015, 15:24
Приложил действующий код с контекстным меню создания папки, с надеждой что подсказка все таки будет.
К сожалению задача осталась не решенной.
Пересортировка дерева после создания новой папки не происходит. Сейчас же папка создается в конце текущей ветки.

При Drag and Drop из одной папки в другую в оригинальной версии программы срабатывает автосортировка, значит отсылка какого то сигнала есть.
Однако в прикрепленном примере и это не работает.


Название: Re: QTreeView + QFileSystemModel - Drag and Drop
Отправлено: Serega от Апрель 04, 2015, 05:38
Методом упорного тыка, все таки, удалось заставить правильно работать сортировку:
Код:
  m_managerView->sortByColumn(1, Qt::AscendingOrder);
  m_managerView->sortByColumn(0, Qt::AscendingOrder);
Или так:
Код:
  managerModel->sort(1, Qt::AscendingOrder);
  managerModel->sort(0, Qt::AscendingOrder);  
Как видим, компактно, но как то странно-некрасиво да и не понятно, почему именно так. К тому же в тестовом коде не хочет работать. Ну может что то не аккуратно переснял. Возможно кого то наведет на мысль такое поведение и пояснит суть.
Тем не менее в оригинале работает как часы.

Но вот такая проблемка осталась. В оригинале после создания папки, папка теперь встает на своеместо в дереве. Однако после этого я позволяю пользователю дать ей имя:
Код:
  managerModel->mkdir(index, newNameFolder);
  index = managerModel->index(newFullNameFolder);
  m_managerView->setCurrentIndex(index);

  m_managerView->edit(index); //NEW NAME
  m_managerView->sortByColumn(1, Qt::AscendingOrder);
  m_managerView->sortByColumn(0, Qt::AscendingOrder);
Если меняем имя, дальнейшей пересортировки уже не происходит.
Соответственно вопрос. Как теперь связать изложенный способ пересортировки с изложенной ситуацией? Т.е. ясно, что как то надо определить, что пользователь ввел новое имя и вызвать метод, созданный на основе вышеизложенного способа.
Т.е. вопрос в том как определить, что пользователь закончил ввод нового имени?



P.S. Попутный вопрос не относящийся к сабжу. Почему при редактировании топика повторно не получатся использовать code=cpp. Код выглядит так:
&#160;m_managerView->sortByColumn(1, Qt::AscendingOrder);


Название: Re: QTreeView + QFileSystemModel - Drag and Drop
Отправлено: Serega от Апрель 05, 2015, 06:54
Ну что ж пока опять методом упорного тыка наткнулся на простейший вариант:
Код
C++ (Qt)
 connect( managerModel, SIGNAL( fileRenamed( QString, QString, QString ) ),
          this, SLOT( sortTree() ) );
 
...
...
 
void managerWidget::sortTree()
{
 m_managerView->sortByColumn(1, Qt::AscendingOrder);
 m_managerView->sortByColumn(0, Qt::AscendingOrder);
}
Отрабатывает как изменения имен файлов так и каталогов.