Russian Qt Forum

Qt => 2D и 3D графика => Тема начата: MetalKrot от Февраль 26, 2014, 09:36



Название: QGraphicsItem и exposedRect
Отправлено: MetalKrot от Февраль 26, 2014, 09:36
Такая проблема. Имеется QGraphicsItem. В методе paint нужно узнать какой именно прямоугольник на данный момент виден во вьюшке. Пытался через option->exposedRect, но здесь возвращается не всегда правильное значение. Точнее оно само по себе правильно, только мне не подходит. Присылается только та часть, которая на данный момент ещё не отрисована, тоесть сцена всё остальное хранит в кэше.
Я же хочу получить координаты и размеры всего прямоугольника, который отрисовывается на данный момент.
Я делал так, но понятно дело что это костыль:
Код:
    QRectF exposedRect(scene()->views().first()->viewport()->rect());
    QPolygonF sceneRect = scene()->views().first()->mapToScene(exposedRect.toRect());
    exposedRect.setTopLeft(sceneRect.at(0));
    exposedRect.setBottomRight(sceneRect.at(2));
В принципе первую строку можно записать проще:
Код:
QRectF exposedRect(widget->rect());

Но сути это не поменяет. Я не смогу переконвертировать координаты без метода mapToScene, который лежит во вьюшке...

Может у кого-нибудь есть на этот счёт идеи или же возможно кто-то уже сталкивался с этим?


Название: Re: QGraphicsItem и exposedRect
Отправлено: GreatSnake от Февраль 26, 2014, 10:27
Похоже что что-то не так с пониманием QGraphicsScene/QGraphicsView.
QGraphicsItem принадлежит сцене и вся отрисовка делается именно на ней.
Если в QGraphicsItem::paint() возникает желание достучаться до вью, то нужно сразу задуматься об архитектуре ибо это как-минимум моветон и как-максимум путь в никуда.


Название: Re: QGraphicsItem и exposedRect
Отправлено: MetalKrot от Февраль 26, 2014, 10:35
Цитировать
ибо это как-минимум моветон и как-максимум путь в никуда
это я понимаю. но ситуация так сложилась, что другого выхода я не вижу. нужно знать и всё)
item по размеру очень большой. отрисовывает карту местности. для отрисовки используется система тайлов. всё бы ничего, но нужно сделать так, чтобы тайлы отображались в определенном порядке. тоесть от центра к краям монитора. вот здесь exposedRect и не подходит..


Название: Re: QGraphicsItem и exposedRect
Отправлено: GreatSnake от Февраль 26, 2014, 10:40
item по размеру очень большой. отрисовывает карту местности. для отрисовки используется система тайлов.
Может стоит на каждый тайл иметь свой sub-item?
Иначе какой смысл заводить сцену и иметь в ней один огромный айтем?


Название: Re: QGraphicsItem и exposedRect
Отправлено: MetalKrot от Февраль 26, 2014, 10:43
Цитировать
Может стоит на каждый тайл иметь свой sub-item?
а каким образом тогда организовать нужный мне порядок отрисовки? картинка грузится с сервера, это может занять от нескольких сотен милисекунд, до нескольких секунд и даже минут. всё в другом потоке естественно.


Название: Re: QGraphicsItem и exposedRect
Отправлено: GreatSnake от Февраль 26, 2014, 10:53
а каким образом тогда организовать нужный мне порядок отрисовки?
А надо ли что-то организовывать?
Пусть сам вью и отрисует видимые sub-items во вьюпорте.

Только ни в коем случае для тайла не задействуй QGraphicsPixmapItem.
Храни всё в QImage и сам отрисовывай.


Название: Re: QGraphicsItem и exposedRect
Отправлено: MetalKrot от Февраль 26, 2014, 11:00
я же говорю, картинки грузятся долго. поэтому нету смысла показывать пользователю узкую полоску сверху монитора. карту нужно грузить начиная из центра. на данный момент оптимальный размер тайлов выбрали 250-350 пикселей. при других размерах падает скорость отображения.
вот теперь представьте: от сцены приходит запрос на отрисовку. айтем начинает грузить картинки для отображения (допустим размером 250 пикселей и каждая грузится 1 секунду). допустим, что верхний слой тайлов не полностью помещается на экране, но отобразить их надо. посчитайте за какой промежуток времени пользователь увидит отображённую карту в центре монитора. а через сколько времени увидит всю карту? а сможет ли он работать, если видит только полоску вверху монитора шириной в 200 пикселей? а следующая такая полоска будет грузиться примерно 7-8 секунд.


Название: Re: QGraphicsItem и exposedRect
Отправлено: MetalKrot от Февраль 26, 2014, 11:02
Цитировать
Только ни в коем случае для тайла не задействуй QGraphicsPixmapItem.
Храни всё в QImage и сам отрисовывай.
А разве можно использовать QImage не в GUI потоке? По-моему нельзя.
А чем плох QPixmap? У меня тайл содержит в себе QPixmap и QRect, на котором он рисуется.


Название: Re: QGraphicsItem и exposedRect
Отправлено: GreatSnake от Февраль 26, 2014, 11:13
А разве можно использовать QImage не в GUI потоке? По-моему нельзя.
Как раз QImage для этого и предназначен, т.к. хранится в program-space.
Цитировать
А чем плох QPixmap? У меня тайл содержит в себе QPixmap и QRect, на котором он рисуется.
А вот QPixmap хранится в window-system-space и их количество лимитировано (как минимум под виндами).

Вообще нужно придерживаться практики использования пиксмапов только для небольших и статических картинок.


Название: Re: QGraphicsItem и exposedRect
Отправлено: GreatSnake от Февраль 26, 2014, 11:55
вот теперь представьте: от сцены приходит запрос на отрисовку. айтем начинает грузить картинки для отображения (допустим размером 250 пикселей и каждая грузится 1 секунду).
Т.е. загрузкой тайла занимается айтем ???
Можно тогда найти неподгруженный айтем через
Код
C++ (Qt)
QGraphicsItem * QGraphicsView::itemAt ( const QPoint & pos ) const
и активировать его загрузку.


Название: Re: QGraphicsItem и exposedRect
Отправлено: MetalKrot от Февраль 26, 2014, 12:35
Если бы можно было искать айтемы по прямоугольнику было бы лучше. а по точке.. ну представьте, у меня на монитор 10 айтемов помещается. по какой точке я буду их все 10 искать?
айтем не сам грузит. от создаёт таски и отправляет их рендеру. рендер уже грузит картинки. айтем только отрисовывает их.
к тому же у меня на сцене будет несколько таких айтемов. каждый будет отвечать за отображение различных объектов. система хитрая (и возможно не совсем правильная). посмотрим что получится, когда буду запускать это всё вместе)


Название: Re: QGraphicsItem и exposedRect
Отправлено: Fregloin от Март 01, 2014, 11:20
если такая скорость, может есть смысл подумать над кешированием картинок на стороне клиента?


Название: Re: QGraphicsItem и exposedRect
Отправлено: MetalKrot от Март 03, 2014, 14:24
Хэширование есть. Но много тоже не захэшируешь, карта большая, картинок много получится. Хэширую только часть.


Название: Re: QGraphicsItem и exposedRect
Отправлено: OKTA от Март 03, 2014, 15:13
Кэш != Хэш  ;D


Название: Re: QGraphicsItem и exposedRect
Отправлено: MetalKrot от Март 05, 2014, 09:59
Да, сглупил. Но на данный момент я Кэширую при помощи Хэша о_О


Название: Re: QGraphicsItem и exposedRect
Отправлено: OKTA от Март 05, 2014, 10:03
О_о how?))


Название: Re: QGraphicsItem и exposedRect
Отправлено: MetalKrot от Март 05, 2014, 12:39
сложно рассказать)))
мне нужно кэшировать определенные элементы, а не те, которые захочет сам кэш (QCache). поэтому пришлось отказаться от него и использовать QHash (доступ по ключу и т.д.). после этого у меня кэшируются элементы, отображённые на экране, и ещё некоторое количество элементов рядом (рамкой вокруг экрана).
теперь, когда картинка загрузилась, я могу менять положение экрана (тупо сказано) и постоянно видеть на экране картинку, т.к. то место, куда экран попал, уже загружено (осталось только отрисовать). потом ненужные картинки удалятся и на их место загрузятся новые. опять же рамкой вокруг экрана.

кароч, много текста и мыслей. если будут вопросы - сделаю картинку и закину сюда. только скажите на какой файлопомойк её закинуть.