LINUX.ORG.RU

А расскажите мне про Qt еще!

 , ,


1

2

Есть у меня вопросы касаемо QGraphics- Scene, Item и View.

Открываем https://doc.qt.io/qt-5/qtwidgets-graphicsview-chip-example.html

Я не совсем въехал что там за вумный алгоритм отрисовки видимой части сцены. Но мне кажется что он совсем не вумный.

И вот почему — в наследнике от QGraphicsItem (в примере это чип) определен метод рисования, он низкоуровневый — пейнтером, который клал болт на определение видимой части сцены. И если чип маленький, то в моем случае элементы будут почти всегда намного больше амбразуры вьюпорта. Это рисовать же будет полностью! Не?

Бродят мысли влепить тупо виджет и для вида бросить подле него два скроллбара. Рисовать видимые части элементов так же пейнтером, заранее просчитав что там должно быть видно, а вместо зума, зная, положение скроллбара и координаты где элемент заканчивается — рисовать (или нет) конец элемента (нужную часть внешней границы).

Так вот. Повторю — не хочу наступать на грабли, и велосипедить тоже не очень хочу. Как реально работает этот QGraphics* ?

Сцена меняет размеры на максимально занятые элементами, а вьюха забирает эти размеры чтобы актуализировать скроллбары... Т.е. так и так рисует полностью?

Ответ на: комментарий от Dendy

Ок, допустим этот флаг действует. Сама сцена точно может определить кого ей сейчас надо рисовать, а кого нет.

Кстати, этот флаг и интерактив отключает, т.е. работает только для тех, кто в амбразуру реально не попал.

Но вот если видна часть элемента — это сможет определить только элемент. Ибо сцена уже запустила его метод рисования...

Как внутри элемента размером в 1000000 пикселей при макс зуме проверить какую часть себя рисовать не надо? Правильно — спросить сцену, вьюху и скроллы, определить какая часть тебя будет видна, скорректировать отрисовку, пусть грубо, с запасом, но не весь мильён пихулей с метками, текстом и еще кучей всякого.

Т.е. велосипедить все же придется. Ибо в таком случае сцена является не нужной прослойкой — перебирает элементы для проверки кто попал на показ. В моем видении проще отдать проверку самим элементам, которую в любом раскладе придется писать.

Я не прав?

deep-purple ★★★★★
() автор топика
Ответ на: комментарий от deep-purple

Серия QGraphicsItem'ов уже представляет собой иерархию, по сути сцена это один корневой элемент, внутрь которого можно засовывать другие.

Насколько я понимаю, идеологически элементы рисуются полностью, без проверки попадают ли они во viewport отдельного QGraphicsView. Сами элементы должны содержать достаточно немного операций рисования, тогда они оптимизируются самим QPainter'ом, отсекая невидимые части. Если одновременно на экране тысячи элементов, то будет больше накладных расходов, когда каждый будет заниматься проверкой видимой части, чем пожертвовать теми, что попали на край viewport'а.

Глобальная же оптимизация проводится отсекая некоторые элементы целиком, boundingRect которых не попал во viewport. Догадываюсь, что масштабирование там имеет логарифмическую глубину, оптимально сортируя элементы на ходу при их трансформации, чтобы позже мгновенно находить видимые даже если их сотни тысяч.

Dendy ★★★★★
()

пейнтером, который клал болт на определение видимой части сцены

Пеинтеру можно задать clipRect, и тогда всё будет ок.

Сцена меняет размеры на максимально занятые элементами

По умолчанию. Но можно задать sceneRect.

Лично я, для простых задач, использую тупо виджет, ибо в сцене слишком много нагорожено. Но если нужно «отрезать лишние» и нужна иерархия - то проще использовать сцену.

RazrFalcon ★★★★★
()
Ответ на: комментарий от deep-purple

Сегменты путей не сильно жрут память и цпу, а текст (теоретически) должен обрабатываться отдельно, хотя хз как этот qt внутри устроен. По факту по опыту, ты можешь вообще всю сцену рисовать в zerorect clip и едва ли пробьешь 10% на ядре – самое дорогое это непосредственно отрисовка. Если только у тебя не реальный прям хуилион примитивов. К тому же сцена может оказаться внезапно кеширующей, например (хз). Тут всегда надо мерять конкретный сетап, потом дергаться.

anonymous
()
Ответ на: комментарий от Dendy

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

deep-purple ★★★★★
() автор топика
Ответ на: комментарий от RazrFalcon

Да. Да.

Насчет иерархии можно пример? Чот не гуглится как Item вложить в Item и чтобы автоматом проверялось и не вызывалось рисование потомка если он не виден.

deep-purple ★★★★★
() автор топика
Ответ на: комментарий от anonymous

Значит и ты за сцену. А что насчет велосипедной имитации большого размера? Вот как я выше писал. Пользователь скролл крутнун, а я репейнт сделал — укоротил гориз линии, нарисовал верт линию конца полоски?

deep-purple ★★★★★
() автор топика
Ответ на: комментарий от deep-purple

Это тебе виднее. И так, и так вопрешься во что-то, в зависимости от будущих хотелок и ui-перфекционизма. Либо будешь воевать с их утырочным кодом, либо свой костылять. Тяжелые фреймворки работают как часы на обычных задачах, и нихрена не проработаны для кастомных.

anonymous
()
Ответ на: комментарий от anonymous

Фак, ты меня огорчил, мне нихрена не виднее, беда.. Как же ты прав насчет стандартных задач и перфефапания на уи.. Короче повелосипедю — отпишусь что вышло.

deep-purple ★★★★★
() автор топика
Ответ на: комментарий от RazrFalcon

А вот не угадал. Нет такого метода у график-итема! Только в конструктор передать можно, значит и репарент не сделать.

deep-purple ★★★★★
() автор топика
Ответ на: комментарий от anonymous

Анончик! Ты опять прав — воюю с утырочным кодом, еще чуть и начну велик писать.

deep-purple ★★★★★
() автор топика

не хочу наступать на грабли

Так без этого никак.

и велосипедить тоже не очень хочу

Я тут перечитываю Кернигана с братом его Ритчи и припоминаю, что в кусках кода, которые поразбросаны то там то сям, велосипедов столько, что ими хватит оснастить нанайскую стрелковую горно-верблюжью дивизию.

Deleted
()
Ответ на: комментарий от RazrFalcon

Хм... Тогда все не так печально. Спасибо.

deep-purple ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.