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

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

Страниц: 1 [2] 3   Вниз
  Печать  
Автор Тема: QGraphicsItem и трансформации систем координат  (Прочитано 22967 раз)
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #15 : Август 09, 2011, 11:35 »

Вот как пример: Вся эта куча трансформаций и систем координат. В QPainter своя матрица трансформации, в QGraphicsView своя матрица трансформации, у QGraphicsItem тоже есть своя матрица трансформации, а толку?
В QPainter матрица берётся от QGraphicsView и перемножается на матрицу QGraphicsItem, если оная у него имеется.
Записан

Qt 5.11/4.8.7 (X11/Win)
iroln
Гость
« Ответ #16 : Август 09, 2011, 14:43 »

Цитировать
А кто мешает в frameSectionAt() увеличить границы.
Да это не поможет. Дело в другом. В вашем коде событие сработает только когда курсор мыши попадёт в активную область айтема, поэтому половина ручки игнорируется. Точность границы айтема можно задать через boundingRect() и shape(), у вас просто shape не переопределён, поэтому используется область по умолчанию. И ещё что-то с определением попадания не так, области ручек как будто бы сдвинуты внутрь айтема.

Я вообще не очень понимаю, почему Вы обрабатываете событие попадания в ручку айтема в классе вида, когда это можно делать непосредственно в классе айтема, например, в функции hoverEnterEvent(). При этом для айтема точно так же можно определить точность границ через функции boundingRect() и shape(), которые будут учитывать размеры ручек, что, кстати позволит сделать отслеживание области ресайза по всему периметру рамки, а не только внутри ручек.

Я сделаю вариант инстурмента по вашему примеру, сравню работоспособность и удобство использования, скорость и прочее. Выберу, что больше понравится и будет лучше работать. Улыбающийся

Цитировать
Иначе одновременно рисовать с трансформациями и без не получится.
У меня получилось. Я рисую родительский айтем рамки с трансформациями пером нулевой толщины, а потомки-айтемы ручек рисую с игнорированием трнасформаций, просто задавая для них позицию, привязанную к координатам родительского айтема. Получается, что ручки всегда стоят на своих местах и не изменяют размер при любом масштабе.
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #17 : Август 09, 2011, 16:09 »

Цитировать
А кто мешает в frameSectionAt() увеличить границы.
Да это не поможет. Дело в другом. В вашем коде событие сработает только когда курсор мыши попадёт в активную область айтема, поэтому половина ручки игнорируется. Точность границы айтема можно задать через boundingRect() и shape(), у вас просто shape не переопределён, поэтому используется область по умолчанию. И ещё что-то с определением попадания не так, области ручек как будто бы сдвинуты внутрь айтема.
Исправил. При поиске элемента использвался режим Qt::IntersectsItemShape, а нужен Qt::IntersectsItemBoundingRect.

Цитировать
Я вообще не очень понимаю, почему Вы обрабатываете событие попадания в ручку айтема в классе вида, когда это можно делать непосредственно в классе айтема, например, в функции hoverEnterEvent().
Дело в том, что я испульзую один айтем для отрисовки "ручек", поэтому hoverEnterEvent() мне ничего не даст. А вот помог бы QGraphicsItem::mouseMoveEvent(), но он отрабатывает только при нажатой кнопке - косяк Qt?

Цитировать
Цитировать
Иначе одновременно рисовать с трансформациями и без не получится.
У меня получилось. Я рисую родительский айтем рамки с трансформациями пером нулевой толщины, а потомки-айтемы ручек рисую с игнорированием трнасформаций, просто задавая для них позицию, привязанную к координатам родительского айтема. Получается, что ручки всегда стоят на своих местах и не изменяют размер при любом масштабе.
А вот это наверное самое правильное решение) Про sub-items изначально я и не подумал.
« Последнее редактирование: Август 09, 2011, 16:15 от GreatSnake » Записан

Qt 5.11/4.8.7 (X11/Win)
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #18 : Август 09, 2011, 17:45 »

У меня получилось. Я рисую родительский айтем рамки с трансформациями пером нулевой толщины, а потомки-айтемы ручек рисую с игнорированием трнасформаций, просто задавая для них позицию, привязанную к координатам родительского айтема. Получается, что ручки всегда стоят на своих местах и не изменяют размер при любом масштабе.
Что значит "просто рисую" - а как boundingRect ручек?

Зачем так сложно Непонимающий Чем не устраивает мой вариант?
Что вы выиграете от разбивки grips-ов на отдельные элементы? Да ещё создавая кучу сцен.
Не понимаю. Зачем из простой задачи устраивать такие сложности?
Да все Вы прекрасно понимаете Улыбающийся Каждая из ручек по сути "айтем" поскольку обладает всеми его свойствами "графической единицы" - может быть включена или скрыта, выбрана и.т.п. Сваливать всю эту ф-циональность на родителя не по уму. Предположим появился еще треугольник - у него 3 ручки (по углам) что будете делать? Создавать какой-то базовый класс (на том основании что оба "имеют ручки")? Нормальное решение - есть парент-айтем, у него чайлд-айтемы которые двигаются вместе с ним. Если же чайлд-айтем драгается - значит это ресайз парента. Попытки переломить эту естественность (через paintEvent парента и.т.п) будут автоматычно порождать одну проблему за другой - нет даже смысла терять время на их обсуждение.
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #19 : Август 09, 2011, 18:02 »

Сваливать всю эту ф-циональность на родителя не по уму.
Я всё никак не могу понять про какого "родителя" идёт речь?

Цитировать
Предположим появился еще треугольник - у него 3 ручки (по углам) что будете делать? Создавать какой-то базовый класс (на том основании что оба "имеют ручки")? Нормальное решение - есть парент-айтем, у него чайлд-айтемы которые двигаются вместе с ним. Если же чайлд-айтем драгается - значит это ресайз парента.
Вот как раз в моём случае в одном универсальном классе это будет легко реализовать. Стоит только в качестве базы использовать QGraphicsPolygonItem и на вершины навесить ручки.

Цитировать
Попытки переломить эту естественность (через paintEvent парента и.т.п) будут автоматычно порождать одну проблему за другой - нет даже смысла терять время на их обсуждение.
Ну вот опять родителя вспомнили) Не понимаю про какие проблемы Вы говорите. Я их не вижу.

PS. Хм... похоже Вы не поняли идею, хотя я про неё и не говорил) Этот RubberItem является просто инструментом для растяжки существующих элементов сцены. При клике на элемент этот RubberItem просто помещается на выбранный элемент и уже управляет им. Обычно так в редакторах делается.
« Последнее редактирование: Август 09, 2011, 18:07 от GreatSnake » Записан

Qt 5.11/4.8.7 (X11/Win)
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #20 : Август 09, 2011, 18:33 »

Я всё никак не могу понять про какого "родителя" идёт речь?
То что у Вас QGraphicsRectItem - который нужно сайзить, на что навешаны ручки (handles)

Вот как раз в моём случае в одном универсальном классе это будет легко реализовать. Стоит только в качестве базы использовать QGraphicsPolygonItem и на вершины навесить ручки.
Сомнительная общность. Часто встречается круг - и даже полукруг который нужно сайзить интерактивно. Даже если полигон - он может иметь слишком много точек чтобы каждая была handle

А главное - handle явно класс, то уже парент решит сколько handles навесить и где. А как Вы сделаете его классом если у Вас все свалено в paintEvent, разборки курсора  и.т.п? Это конечно можно сделать но совсем непросто и получается какой-то EquippedGraphicsItem (который может иметь и управлять handles). Приходим опять к QGtapgicsItemGroup. Я люблю изобретать велосипед - но все же не настолько  Улыбающийся
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #21 : Август 09, 2011, 19:14 »

2 Igors :
Судя по Вашей логике, каждый элемент сцены должен иметь набор "ручек" Непонимающий
Записан

Qt 5.11/4.8.7 (X11/Win)
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #22 : Август 09, 2011, 19:45 »

2 Igors :
Судя по Вашей логике, каждый элемент сцены должен иметь набор "ручек" Непонимающий
В 3D сцене - да, и во многих вариантах (когда объект выбран)

- просто 3D объект (простейший случай). Вращать его интерактивно надо? И к бабке не ходи - надо. Двигать вдоль каждой из осей или free - стопудово. Ну и сайзить тоже бы неплохо.

- 3D light - ну тут засада (dropoff, направление, размеры источника света - по всякому, радиус тумана, радиус flare и.т.п.) - там приходится иметь опции "какие handles показывать" - иначе ховайся

- остальные - еше хуже

Так что не дело все лить в paintEvent
Записан
iroln
Гость
« Ответ #23 : Август 09, 2011, 20:43 »

Что значит "просто рисую" - а как boundingRect ручек?
Прошу прощения, неверно выразился. Не рисую, а создаю айтемы. Каждая ручка - это айтем - потомок айтема рамки. boundingRect у каждой ручки соответственно свой, ну а дальше всё работает так как Вы описали: Ручки можно скрыть, показать, они связаны сигналами со своим родителем и если я их тащу, родитель изменяет размер, ну и т.д.
В такой реализации осталась одна проблема (на самом деле две, но первая проблема более неприятная). Я не могу задать для айтемов ручек такой boundingRect, который бы распространялся на все грани родительского айтема, чтобы ресайзить можно было за края айтема, а не толкьо за ручки, ну удобнее так просто-напросто. А так как родитель принимает трансформации, а ручки их игнорируют, то без знания масштаба внутри boundingRect ручки не вычислить размер грани родительского айтема, вернее вычислить то можно, а вот задать правильный boundingRect никак нельзя, так как он будет игнорировать трансформации и всегда будет фиксированного размера, а не изменяться вместе с родительским айтемом.

Вторая проблема - это как раз толщина линии (Pen) родительского айтема, я могу ставить её только равной нулю, иначе она будет иметь размер в пикселях изображения, ну то-есть сцены. Я вообще не пойму, почему такие простые вещи нельзя сделать, например задать толщину линии, не зависящую от масштаба (в координатах области отображения), но чтобы сама линия масштабировалась, это же просто жизненно необходимо!

Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #24 : Август 09, 2011, 21:19 »

Я вообще не пойму, почему такие простые вещи нельзя сделать, например задать толщину линии, не зависящую от масштаба (в координатах области отображения), но чтобы сама линия масштабировалась, это же просто жизненно необходимо!
Код
C++ (Qt)
void QPen::setCosmetic ( bool cosmetic )
Записан

Qt 5.11/4.8.7 (X11/Win)
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #25 : Август 09, 2011, 21:26 »

2 Igors :
Судя по Вашей логике, каждый элемент сцены должен иметь набор "ручек" Непонимающий
В 3D сцене - да, и во многих вариантах (когда объект выбран)
Опять с Вами не соглашусь)
Всё-таки здесь разговор идёт про 2D, а не про 3D.
Записан

Qt 5.11/4.8.7 (X11/Win)
kamre
Частый гость
***
Offline Offline

Сообщений: 233


Просмотр профиля
« Ответ #26 : Август 09, 2011, 21:28 »

Вторая проблема - это как раз толщина линии (Pen) родительского айтема, я могу ставить её только равной нулю, иначе она будет иметь размер в пикселях изображения, ну то-есть сцены. Я вообще не пойму, почему такие простые вещи нельзя сделать, например задать толщину линии, не зависящую от масштаба (в координатах области отображения), но чтобы сама линия масштабировалась, это же просто жизненно необходимо!
Именно по этой причине я отказался от QGraphicsView Framework и начал писать свою реализацию под задачу. А причина более или менее понятна: bounding box в системе координат сцены у такого отрезка постоянной толщины будет постоянно меняться, а весь индекс для items  основан именно на этих bounding boxes.

При этом Nokia считает этот framework как Done и развивать больше не собирается.
Записан
kamre
Частый гость
***
Offline Offline

Сообщений: 233


Просмотр профиля
« Ответ #27 : Август 09, 2011, 21:35 »

Код
C++ (Qt)
void QPen::setCosmetic ( bool cosmetic )
А теперь внимательно читаем: QGraphicsItem does not support use of cosmetic pens with a non-zero width.
Записан
iroln
Гость
« Ответ #28 : Август 09, 2011, 22:36 »

Код
C++ (Qt)
void QPen::setCosmetic ( bool cosmetic )
А теперь внимательно читаем: QGraphicsItem does not support use of cosmetic pens with a non-zero width.
Я несколько раз перечитывал описание метода paint() но так до конца и не понял, что они хотели сказать в этом предложении (QGraphicsItem does not support use of cosmetic pens with a non-zero width) применительно к отрисовке айтема. Понятно, что надо рисовать в границах boundingRect, иначе артефакты будут вылезать, но как cosmetic на это влияет?

Да в принципе это работает. Перо не меняет толщину при трансформациях. Одной проблемой меньше, запишем в Evernote ещё одну заметку в Qt-блокнотик. Cosmetic... млин, как интуитивно просто связать это с неизменностью ширины линии. Улыбающийся
« Последнее редактирование: Август 09, 2011, 22:49 от iroln » Записан
kamre
Частый гость
***
Offline Offline

Сообщений: 233


Просмотр профиля
« Ответ #29 : Август 10, 2011, 00:14 »

Понятно, что надо рисовать в границах boundingRect, иначе артефакты будут вылезать, но как cosmetic на это влияет?

Представим, что сделали zoom out так, что все очень мелко стало. При этом bounding box в координатах сцены стал меньше толщины кисти, которая cosmetic и от zoom не зависит.
Записан
Страниц: 1 [2] 3   Вверх
  Печать  
 
Перейти в:  


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