Название: DnD в дереве Отправлено: Igors от Июнь 20, 2017, 17:17 Добрый день
Есть QTreeWidget, юзер выбрал неск айтемов и тянет их. Допустим мыша оказалась сейчас между item1 и item2. Как определить можно ли туда вставить выбранное (и значит нарисовать намек - линию разделителя) или нет? Собсно требуется точно такое же поведение как у Xcode когда дропаем файлы в проект Спасибо Название: Re: DnD в дереве Отправлено: Авварон от Июнь 20, 2017, 17:26 Код: QAbstractItemModel::canDropMimeData Название: Re: DnD в дереве Отправлено: Igors от Июнь 21, 2017, 12:31 Код: QAbstractItemModel::canDropMimeData Цитировать Лучшие друзья девушек это бриллианты :)Но и в этом случае его надо писать. Упростим задачу - нет никаких mime, нас интересует только move нодов, драг происходит в одном дереве, selection известен (т.е. строго говоря это не DnD). Если точка вставки известна, то дальше все очевидно (take + insert) Название: Re: DnD в дереве Отправлено: Авварон от Июнь 21, 2017, 15:16 DnD во вью уже реализован и вызывает методы модели. Написать модель много раз проще, чем повторно перекрывать DnD.
Он не так прост, я когда-то курил этот код. Лучше через модель. Можно даже через StandardItemModel - почти как тривиджет, только модель. Upd: ну и при реализации DnD руками от MimeData никуда не уйти:) Название: Re: DnD в дереве Отправлено: Авварон от Июнь 21, 2017, 15:22 Ну в простейшем случае, есть флажки у вьюхи, которые разрешают/запрещают мув айтемов.
Соответственно, никакой логики по запрету (верно я понял, что нужно именно это?) написать не получится. Если же не требуется никакой логики, то юзайте флажки, мув должен автоматом работать. Название: Re: DnD в дереве Отправлено: gil9red от Июнь 21, 2017, 15:25 У меня в старой проге было дерево с папками и элементами в них, ну и работало перетаскивание мышкой в папки. Можно было сразу кучу так брать и бросать в папку, правда код не мой и давно это было...
Та модель дерева: .h (https://github.com/gil9red/NotesManager/blob/master/NavigationPanel/hierarchymodel.h) и .cpp (https://github.com/gil9red/NotesManager/blob/master/NavigationPanel/hierarchymodel.cpp) Название: Re: DnD в дереве Отправлено: Igors от Июнь 21, 2017, 15:59 Что касается "оформления" (отслеживания мыши и.т.п.) - с этим проблем нет. К слову: влезать во все эти mime, drag/drop event'ы есть смысл если DnD планируется между приложениями (редко) или хотя бы между разными виджетами/окнами одного приложения. Если же, как в данном случае, все в рамках одного дерева - проще самому. Ну в самом деле, чего светить dragImage за пределами виджета если никаких дропов там делать не собирались? Да и имедж тот у них совсем колхозный
Лучше через модель. Ну так об этом и вопрос, ..мув должен автоматом работать. Простой пример иерархииЦитировать Item0 Юзер не может вставить Item1 между его чайлдами Item1_1 и Item1_2. Однако это лишь простейший случай, есть и много других - вот о чем я хотел поговоритьItem1 (selected, dragged) Item1_1 <---- мышь здесь Item1_2 Название: Re: DnD в дереве Отправлено: Авварон от Июнь 21, 2017, 16:32 Что касается "оформления" (отслеживания мыши и.т.п.) - с этим проблем нет. К слову: влезать во все эти mime, drag/drop event'ы есть смысл если DnD планируется между приложениями (редко) или хотя бы между разными виджетами/окнами одного приложения. Если же, как в данном случае, все в рамках одного дерева - проще самому. Ну в самом деле, чего светить dragImage за пределами виджета если никаких дропов там делать не собирались? Да и имедж тот у них совсем колхозный Лучше через модель. Ну так об этом и вопрос, ..мув должен автоматом работать. Простой пример иерархииЦитировать Item0 Юзер не может вставить Item1 между его чайлдами Item1_1 и Item1_2. Однако это лишь простейший случай, есть и много других - вот о чем я хотел поговоритьItem1 (selected, dragged) Item1_1 <---- мышь здесь Item1_2 Что значит "проще самому?" У вас в драг эвент приходить MimeData и от неё никуда не деться. Что вы в неё положите (ид айтема или тупо row/column/parent) это ваше дело. По сути, это просто контейнер и вы сейчас звучите "зачем в QMap лезть разбираться, можно же самому, руками" Название: Re: DnD в дереве Отправлено: Igors от Июнь 21, 2017, 16:47 По сути, это просто контейнер и вы сейчас звучите "зачем в QMap лезть разбираться, можно же самому, руками" Не надо все понимать слишком буквально. Написать красно-черное дерево руками можно, но это намного сложнее чем прочитать QMap или std::map Что значит "проще самому?" У вас в драг эвент приходить MimeData и от неё никуда не деться. Что вы в неё положите (ид айтема или тупо row/column/parent) это ваше дело. А здесь ситуация другая, резонов задействовать Qt DnD нет, можно mouseMove или еще лучше вторичный цикл событий (как я и делаю). Но все это отношения у теме не имеет- есть выборка (selection) в дереве (неважно как о ней узнали, через мимю или нет) - есть текущая точка вставки от мыши Она валидна или нет? Название: Re: DnD в дереве Отправлено: Авварон от Июнь 21, 2017, 16:49 https://github.com/qt/qtbase/blob/dev/src/widgets/itemviews/qabstractitemview.cpp#L3674
https://github.com/qt/qtbase/blob/dev/src/widgets/itemviews/qabstractitemview.cpp#L2107 Она валидна или нет? https://github.com/qt/qtbase/blob/dev/src/widgets/itemviews/qabstractitemview.cpp#L2145 https://github.com/qt/qtbase/blob/dev/src/widgets/itemviews/qabstractitemview.cpp#L2193 Название: Re: DnD в дереве Отправлено: Igors от Июнь 21, 2017, 17:06 https://github.com/qt/qtbase/blob/dev/src/widgets/itemviews/qabstractitemview.cpp#L2145 Изучение исходников полезно до определенного предела :) Вот та же иерархия что и выше, но мышь сместилась https://github.com/qt/qtbase/blob/dev/src/widgets/itemviews/qabstractitemview.cpp#L2193 Цитировать Item0 И, как ни странно, Item1 сюда мувить можно :)Item1 (selected, dragged) Item1_1 Item1_2 <---- мышь здесь Название: Re: DnD в дереве Отправлено: Авварон от Июнь 21, 2017, 17:09 И чо? Я вам привел код, который это обрабатывает, нет?
Название: Re: DnD в дереве Отправлено: Igors от Июнь 22, 2017, 08:38 И чо? Я вам привел код, который это обрабатывает, нет? К сожалению не обрабатывает. И еще: если Вы заметили то в одно и то же место можно вставить неск способами, в Qt этого ф-ционала нетНазвание: Re: DnD в дереве Отправлено: Авварон от Июнь 22, 2017, 11:33 Ок, покурил ещё, действительно, случай, когда мышь внизу обрабатывается так: вставка идет в рут.
Насчет нескольких способов - можно либо между айтемами воткнуть, либо на сам айтем дропнуть. Или ещё какие способы? Название: Re: DnD в дереве Отправлено: Igors от Июнь 22, 2017, 11:41 Вроде все получилось. Псевдокод
Код Правда это еще далеко не все :) Название: Re: DnD в дереве Отправлено: Авварон от Июнь 22, 2017, 11:51 Непонятно. Вставка только между выбранными айтемами? В поставновке задачи это не сказано:) (как обычно)
Название: Re: DnD в дереве Отправлено: Igors от Июнь 22, 2017, 13:35 Непонятно. Вставка только между выбранными айтемами? В поставновке задачи это не сказано:) (как обычно) А постановка и не должна перечислять все что не запрещено. Код выше по существу находит ту пару айтемов что была бы в дереве если удалить все selected. Дальше мы имеем N слотов для вставки (хотя бы 1 всегда есть). Пример Код Напр depth оказались 4 и 2, значит можно вставить сразу после item1 (верхнего над мышей), на том же уровне или в его чайлдов, можно в конец его парента или в конец его парент-парента, во всех случаях вставляемое появится там где рисовалась линия вставки. По существу все решено, осталось только показать юзверю где текущий слот. Ну то уже чисто подробности рисования и отслеживания мыши |