Russian Qt Forum

Qt => Model-View (MV) => Тема начата: kambala от Июль 04, 2012, 00:55



Название: [РЕШЕНО] определить координаты перетаскиваемого изображения при drag and drop
Отправлено: kambala от Июль 04, 2012, 00:55
Здравствуйте. Имеются наследники QTableView и QAbstractTableModel, реализовываю поддержку drag and drop внутри «себя» (т.е. элементы можно перемещать в пределах одной и той же таблицы). Все элементы отображаются как картинки.

Как получить координаты верхнего левого угла картинки при перемещении в void dragMoveEvent(QDragMoveEvent *event)? event->pos() возвращает координаты курсора относительно таблицы, что мне не подходит.


Название: Re: определить координаты перетаскиваемого изображения при drag and drop
Отправлено: Bepec от Июль 04, 2012, 06:47
А перевести в глобальные нельзя ? Даже с помощью арифметики?
Или я неверно понял вопрос.


Название: Re: определить координаты перетаскиваемого изображения при drag and drop
Отправлено: kambala от Июль 04, 2012, 09:40
event->pos() уже являются глобальными (относительно таблицы), но это координаты курсора, а мне нужны координаты самого изображения (достаточно лишь левого верхнего угла), которое я тащу. ну или хотя бы координаты курсора относительно изображения – из них уже можно будет получить всё что нужно.


Название: Re: определить координаты перетаскиваемого изображения при drag and drop
Отправлено: _OLEGator_ от Июль 04, 2012, 09:51
Поидее как то так:
Код
C++ (Qt)
QPoint QDrag::hotSpot () const


Название: Re: определить координаты перетаскиваемого изображения при drag and drop
Отправлено: kambala от Июль 04, 2012, 10:09
а как мне получить объект типа QDrag из объекта QDragMoveEvent?


Название: Re: определить координаты перетаскиваемого изображения при drag and drop
Отправлено: _OLEGator_ от Июль 04, 2012, 10:27
Ты же его должен формировать сам в начале перетаскивания.


Название: Re: определить координаты перетаскиваемого изображения при drag and drop
Отправлено: kambala от Июль 04, 2012, 13:29
зачем? за меня ведь это уже делает QTableView (миме-данные с типом application/x-qabstractitemmodeldatalist), а в dropMimeData() модели я расшифровываю миме-данные как мне нужно. или я в корне не понимаю как работает d'n'd?

вьюшка настроена так:
Код
C++ (Qt)
   setDragEnabled(true);
   setAcceptDrops(true);
   setDragDropMode(QAbstractItemView::DragDrop);
   setDragDropOverwriteMode(false);
   setDropIndicatorShown(true);


Название: Re: определить координаты перетаскиваемого изображения при drag and drop
Отправлено: kambala от Июль 05, 2012, 11:42
не люблю «апать» тему, но неужели никто не знает? :)

и еще вопрос назрел: можно ли при перемещении элемента с Qt::MoveAction сразу же убирать его с исходного места, а не только после успешного дропа?


Название: Re: определить координаты перетаскиваемого изображения при drag and drop
Отправлено: Bepec от Июль 05, 2012, 12:18
Как вариант переопределить самому функцию и сразу делать take елемент.


Название: Re: определить координаты перетаскиваемого изображения при drag and drop
Отправлено: kambala от Июль 05, 2012, 16:55
немного поизучав исходники QAbstractItemView, обнаружил, что созданный объект типа QDrag всё время «живёт» во время операции перетаскивания и имеет родителем вьюшку, поэтому его можно легко получить с помощью findChild(), так что теперь целевой индекс в dragMoveEvent и dropEvent рассчитывается так:
Код
C++ (Qt)
QPoint targetPos = event->pos() - findChild<QDrag *>()->hotSpot() + QPoint(rowHeight(0), columnWidth(0)) / 3; // последнее слагаемое определяет допустимый зазор
QModelIndex targetIndex = model()->index(rowAt(targetPos.y()), columnAt(targetPos.x())); // indexAt() в моём случае не подходит

осталось попробовать решить второй вопрос, но тему помечаю как решённую.


Название: Re: [РЕШЕНО] определить координаты перетаскиваемого изображения при drag and drop
Отправлено: kambala от Июль 06, 2012, 02:14
Как вариант переопределить самому функцию и сразу делать take елемент.
если сразу удалять из модели взятый элемент, то программа мгновенно падает :)

с перемещением картинок тоже разобрался (пока только для перемещения по текущему вью, другие ещё не трогал), но тут уже пошли в ход хаки. основные моменты:
  • в dragEnterEvent() запомнить исходный индекс элемента и в data() модели возвращать пустоту когда этот индекс валидный, а также сбросить выделение и спаны
  • в dragLeaveEvent() запускать таймер, который будет проверять осуществляется ли всё ещё перетаскивание (простая проверка findChild<QDrag *>() == 0)
  • «инвалидировать» исходный индекс в dropEvent(), а также в dragLeaveEvent() при условии окончания операции перетаскивания
если кому интересно, завтра могу набросать тестовый проект


Название: Re: [РЕШЕНО] определить координаты перетаскиваемого изображения при drag and drop
Отправлено: Bepec от Июль 06, 2012, 06:48
Пиши. Я с драг и дропом в view ещё не особо копался, мне лично тема очень импонирует :)

PS если самому полностью реализовывать дроп, падать скорее всего не будет. Можно конечно как то скрыть, но хз хз.


Название: Re: [РЕШЕНО] определить координаты перетаскиваемого изображения при drag and drop
Отправлено: _OLEGator_ от Июль 06, 2012, 10:08
Пошли хаки - это признак того, что надо самому писать drag and drop.


Название: Re: [РЕШЕНО] определить координаты перетаскиваемого изображения при drag and drop
Отправлено: kambala от Июль 06, 2012, 10:20
как-то нет желания передирать код из исходников Qt или копаться в платформозависимых функциях самому…


Название: Re: [РЕШЕНО] определить координаты перетаскиваемого изображения при drag and drop
Отправлено: Bepec от Июль 06, 2012, 10:40
Каких платформозависимых Оо?
Вы же внутри программы хотите меняться, не?

Если так то достаточно драги всякие переопределить нафиг и не вызывать функций родителей, не?

PS платформозависимые функции... хм хм хм... чегой то у вас не тогой-то. Драг и дроп то в вашей программе нужен как бэ. Всё как бэ в ваших руках.


Название: Re: [РЕШЕНО] определить координаты перетаскиваемого изображения при drag and drop
Отправлено: _OLEGator_ от Июль 06, 2012, 10:42
Механизм drag and drop открыт для переопределения, если не устраивает стандартная реализация - надо свою писать и не городить огород.


Название: Re: [РЕШЕНО] определить координаты перетаскиваемого изображения при drag and drop
Отправлено: Igors от Июль 06, 2012, 12:19
если кому интересно, завтра могу набросать тестовый проект
Интересно, жду проект. Спасибо


Название: Re: [РЕШЕНО] определить координаты перетаскиваемого изображения при drag and drop
Отправлено: kambala от Июль 06, 2012, 13:06
Каких платформозависимых Оо?
Вы же внутри программы хотите меняться, не?

Если так то достаточно драги всякие переопределить нафиг и не вызывать функций родителей, не?

PS платформозависимые функции... хм хм хм... чегой то у вас не тогой-то. Драг и дроп то в вашей программе нужен как бэ. Всё как бэ в ваших руках.
с перемещением картинок тоже разобрался (пока только для перемещения по текущему вью, другие ещё не трогал), но тут уже пошли в ход хаки
Пошли хаки - это признак того, что надо самому писать drag and drop.
Механизм drag and drop открыт для переопределения, если не устраивает стандартная реализация - надо свою писать и не городить огород.
хаки (таймер вот этот, о котором я писал выше) используются в связке с переопределёнными событиями перемещений. выложу код – посмотрите :)


Название: Re: [РЕШЕНО] определить координаты перетаскиваемого изображения при drag and drop
Отправлено: kambala от Июль 07, 2012, 02:57
прошу прощения что долго не выкладывал пример – день выдался загруженным. выложил код на гитхаб (надо же когда-то попробовать): https://github.com/kambala-decapitator/qt-true-dnd-move

хотел ещё добавить чекбокс чтобы можно было ощутить разницу между стандартной реализацией d'n'd и моей, но уже слишком устал :)

в своём проекте ещё хочу добавить подсветку области дропа (зелёная – можно, красная – нельзя). в примере QTDIR\examples\draganddrop\puzzle\ подобное реализовано через раскраску нужной части виджета с помощью QPainter, но тут думаю можно это реализовать через модель.


Название: Re: [РЕШЕНО] определить координаты перетаскиваемого изображения при drag and drop
Отправлено: kambala от Июль 15, 2012, 15:59
за неделю столько комментариев появилось :)

подсветку (как описывал в предыдущем сообщении) тоже реализовал, но сейчас для этого приходится постоянно вызывать update(), что вызывает ощутимые тормоза. код залью попозже.


Название: Re: [РЕШЕНО] определить координаты перетаскиваемого изображения при drag and drop
Отправлено: Igors от Июль 15, 2012, 17:55
за неделю столько комментариев появилось :)
:) Если бы всегда молчали кому нечего сказать по существу - было бы не так уж плохо.

Я посмотрел Ваш пример, ну все нормально, DnD работает как положено, вызываются соотв методы. Не понял о какой разнице со стандартным Вы говорите. Возможно потому что сам в Qt еще не делал. А разбираться что куда дропается всегда приходится


Название: Re: [РЕШЕНО] определить координаты перетаскиваемого изображения при drag and drop
Отправлено: kambala от Июль 15, 2012, 23:53
дописал «галочку» чтобы была видна разница между стандартной реализацией и кастомной


Название: Re: [РЕШЕНО] определить координаты перетаскиваемого изображения при drag and drop
Отправлено: kambala от Июль 20, 2012, 17:18
добавил подсветку области дропа (зелёный – можно, красный – нельзя). по-моему на мак ос притормаживает перемещение из-за постоянных вызово viewport()->update() в dragMoveEvent (в винде такого не замечаю, а может просто потому что машина мощная). может кто-то подтвердить/опровергнуть?

да, и может уже в отдельную тему пойти с этим вопросом? :)