2015-04-09 3 views
0

Я использую QGraphicsScene для рисования миллионов полигонов. Я планирую использовать Qt + OpenGL позже, но пока я не рисую более 1 миллиона полигонов, а Qt обрабатывает его просто отлично. Проблема возникает, когда я пытаюсь отображать текст внутри полигонов.Показать текст внутри QGraphicsPolygonItem без копирования std :: string в QString?

Каждый многоугольник (собственный класс, наследующий QGraphicsPolygonItem) является визуальным представлением объекта и имеет указатель на связанный с ним объект. Каждый объект имеет идентификатор std::string. Если бы я мог просто показать , что строка внутри полигонов должна быть точной по памяти. Однако Qt, похоже, нуждается в QString, и для преобразования каждой строки требуется много времени и пространства. Я создаю объект QGraphicsTextObject для каждого многоугольника, и каждому из них нужна копия QStringstd::string. Есть ли способ обойти эту копию, используя только Qt?

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

P.S .: Возможно отображение текста по требованию (например, когда пользователь наводит мышь на каждый многоугольник), однако было бы идеально, если бы текст был легко отображен.

ответ

1

Профилировали ли вы его, чтобы убедиться, что преобразование на самом деле является вашим узким местом? Шрифт рендеринга не совсем быстрый, и если на самом деле пытается отобразить миллионы текстов, это будет медленным. Вы не обойдете конверсии строк, единственное, что я могу придумать, - это оптимизировать, когда их делать, и как часто.

Во-первых, я бы подумал о том, чтобы использовать пользовательский элемент, либо покрасив текст вручную, переопределив QGraphicsItem :: paint, либо исходя из, например, QGraphicsSimpleTextItem, что позволяет больше настраивать, чем использовать QGraphicsSimpleTextItem или даже QGraphicsTextItem напрямую, оба из которых требуют вызова setText() и, таким образом, преобразуют строку вверх.

Одна вещь, о которой нужно знать, - это когда будет сделано преобразование. С помощью настраиваемого элемента вам не нужно будет преобразовывать std :: string в преобразование QString upfront (при вызове setText()), но вы можете сохранить std :: string и сделать это только по требованию, в вашей краске (), т. е. конвертировать первый вызов paint(), а затем кешировать.

Еще один потенциально дорогостоящий расчет - boundingRect(). Это может быть изменено путем возврата менее точной аппроксимации фактической текстовой формы. Это не повредит, если возвращенный прямоугольник несколько больше, чем фактически окрашенный прямоугольник, он просто не должен быть меньше. Таким образом, можно использовать жестко закрепленную высоту * прибл. ширина письма + некоторые набивка.

Тогда текст, не нарисованный вообще, еще дешевле. Если представление так уменьшено, то нарисовано 10^6 элементов (и только тогда вызывается paint()), каждый из них будет затруднен для чтения любого текста. Я бы повторно реализовал paint() и использовал механизм детализации QGraphicsView (см. here) и просто не преобразовывал строку и не рисовал что-либо ниже определенного уровня детализации/масштабирования.

Если вы можете использовать Qt 5.4, QGraphicsScene::minimumRenderSize может также пригодиться. Но это само по себе не позволит избежать преобразований строк или boundingRect(), если они не объединены с другими предложениями, приведенными выше.

+0

Я не знал об этих функциях, они помогут вам оптимизировать код. Благодаря! – Alex

Смежные вопросы