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

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

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: QGraphicsItem и exposedRect  (Прочитано 7175 раз)
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, который лежит во вьюшке...

Может у кого-нибудь есть на этот счёт идеи или же возможно кто-то уже сталкивался с этим?
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #1 : Февраль 26, 2014, 10:27 »

Похоже что что-то не так с пониманием QGraphicsScene/QGraphicsView.
QGraphicsItem принадлежит сцене и вся отрисовка делается именно на ней.
Если в QGraphicsItem::paint() возникает желание достучаться до вью, то нужно сразу задуматься об архитектуре ибо это как-минимум моветон и как-максимум путь в никуда.
Записан

Qt 5.11/4.8.7 (X11/Win)
MetalKrot
Гость
« Ответ #2 : Февраль 26, 2014, 10:35 »

Цитировать
ибо это как-минимум моветон и как-максимум путь в никуда
это я понимаю. но ситуация так сложилась, что другого выхода я не вижу. нужно знать и всё)
item по размеру очень большой. отрисовывает карту местности. для отрисовки используется система тайлов. всё бы ничего, но нужно сделать так, чтобы тайлы отображались в определенном порядке. тоесть от центра к краям монитора. вот здесь exposedRect и не подходит..
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #3 : Февраль 26, 2014, 10:40 »

item по размеру очень большой. отрисовывает карту местности. для отрисовки используется система тайлов.
Может стоит на каждый тайл иметь свой sub-item?
Иначе какой смысл заводить сцену и иметь в ней один огромный айтем?
Записан

Qt 5.11/4.8.7 (X11/Win)
MetalKrot
Гость
« Ответ #4 : Февраль 26, 2014, 10:43 »

Цитировать
Может стоит на каждый тайл иметь свой sub-item?
а каким образом тогда организовать нужный мне порядок отрисовки? картинка грузится с сервера, это может занять от нескольких сотен милисекунд, до нескольких секунд и даже минут. всё в другом потоке естественно.
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #5 : Февраль 26, 2014, 10:53 »

а каким образом тогда организовать нужный мне порядок отрисовки?
А надо ли что-то организовывать?
Пусть сам вью и отрисует видимые sub-items во вьюпорте.

Только ни в коем случае для тайла не задействуй QGraphicsPixmapItem.
Храни всё в QImage и сам отрисовывай.
« Последнее редактирование: Февраль 26, 2014, 10:57 от GreatSnake » Записан

Qt 5.11/4.8.7 (X11/Win)
MetalKrot
Гость
« Ответ #6 : Февраль 26, 2014, 11:00 »

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

Цитировать
Только ни в коем случае для тайла не задействуй QGraphicsPixmapItem.
Храни всё в QImage и сам отрисовывай.
А разве можно использовать QImage не в GUI потоке? По-моему нельзя.
А чем плох QPixmap? У меня тайл содержит в себе QPixmap и QRect, на котором он рисуется.
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #8 : Февраль 26, 2014, 11:13 »

А разве можно использовать QImage не в GUI потоке? По-моему нельзя.
Как раз QImage для этого и предназначен, т.к. хранится в program-space.
Цитировать
А чем плох QPixmap? У меня тайл содержит в себе QPixmap и QRect, на котором он рисуется.
А вот QPixmap хранится в window-system-space и их количество лимитировано (как минимум под виндами).

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

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

Сообщений: 2921



Просмотр профиля
« Ответ #9 : Февраль 26, 2014, 11:55 »

вот теперь представьте: от сцены приходит запрос на отрисовку. айтем начинает грузить картинки для отображения (допустим размером 250 пикселей и каждая грузится 1 секунду).
Т.е. загрузкой тайла занимается айтем Непонимающий
Можно тогда найти неподгруженный айтем через
Код
C++ (Qt)
QGraphicsItem * QGraphicsView::itemAt ( const QPoint & pos ) const
и активировать его загрузку.
Записан

Qt 5.11/4.8.7 (X11/Win)
MetalKrot
Гость
« Ответ #10 : Февраль 26, 2014, 12:35 »

Если бы можно было искать айтемы по прямоугольнику было бы лучше. а по точке.. ну представьте, у меня на монитор 10 айтемов помещается. по какой точке я буду их все 10 искать?
айтем не сам грузит. от создаёт таски и отправляет их рендеру. рендер уже грузит картинки. айтем только отрисовывает их.
к тому же у меня на сцене будет несколько таких айтемов. каждый будет отвечать за отображение различных объектов. система хитрая (и возможно не совсем правильная). посмотрим что получится, когда буду запускать это всё вместе)
Записан
Fregloin
Супер
******
Offline Offline

Сообщений: 1025


Просмотр профиля
« Ответ #11 : Март 01, 2014, 11:20 »

если такая скорость, может есть смысл подумать над кешированием картинок на стороне клиента?
Записан
MetalKrot
Гость
« Ответ #12 : Март 03, 2014, 14:24 »

Хэширование есть. Но много тоже не захэшируешь, карта большая, картинок много получится. Хэширую только часть.
Записан
OKTA
Гость
« Ответ #13 : Март 03, 2014, 15:13 »

Кэш != Хэш  Смеющийся
Записан
MetalKrot
Гость
« Ответ #14 : Март 05, 2014, 09:59 »

Да, сглупил. Но на данный момент я Кэширую при помощи Хэша о_О
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


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