В моем QGraphicsRectItem:: краска (), я пытаюсь потянуть название объекта в реагировать (). Однако для каждого из различных объектов, они могут иметь переменную ширину и так же называют, может иметь переменную длину.
В настоящее время я запускаю с максимального размера шрифта, проверяя, соответствует ли он и постепенное уменьшение его, пока я не нахожу размер шрифта, который соответствует. До сих пор я не был в состоянии найти быстрый и простой способ сделать это. Существует ли лучший, или более эффективный способ сделать это?
Спасибо!
void checkFontSize(QPainter *painter, const QString& name) {
// check the font size - need a better algorithm... this could take awhile
while (painter->fontMetrics().width(name) > rect().width()) {
int newsize = painter->font().pointSize() - 1;
painter->setFont(QFont(painter->font().family(), newsize));
}
}
Йоханнес из qtcentre.org предложил следующее решение:
float factor = rect().width() / painter->fontMetrics().width(name);
if ((factor < 1) || (factor > 1.25))
{
QFont f = painter->font();
f.setPointSizeF(f.pointSizeF()*factor);
painter->setFont(f);
}
Я попробовал его в своей программе, и до сих пор он, кажется, работает достаточно хорошо. Мне это нравится, потому что он дает результаты за один проход, но предполагает, что ширина шрифта масштабируется так же, как и его высота.
http://www.qtcentre.org/threads/27839-For-Qt-4-6-x-how-to-auto-size-text-to-fit-in-a-specified-width
К сожалению, нет. Для этого нет простого решения. Наиболее очевидным улучшением с точки зрения производительности было бы вычисление и кеширование необходимого размера шрифта при изменении текста вместо его пересчета в каждом PaintEvent. Еще одно улучшение - попытаться оценить правильный размер на основе пропорций ограничивающего прямоугольника. Создание и тестирование оценок должны помочь вам скорректировать размер гораздо быстрее, чем просто уменьшать размер точки на единицу на каждой итерации.
Вы можете иметь QGraphicsTextItem в качестве дочернего элемента прямоугольного элемента, измерять ширину текстового элемента и затем масштабировать текстовый элемент (setTransform ()), чтобы он соответствовал ширине (и высоте) прямоугольного элемента.
Это зависит от диапазона, в котором вы ожидаете изменения размеров шрифта. Если диапазон большой, то увеличение на единицу может занять много времени. Если речь идет всего лишь о нескольких размерах пункта, скорость, вероятно, не будет проблемой.
Если диапазон большой, другой подход заключается в добавлении большего интервала вместо '1'. Если в течение одного шага вы превысите желаемый размер, уменьшите интервал, скажем, наполовину. Каждый раз вы будете отскакивать назад и вперед от оптимального размера на все меньшую и меньшую величину; когда разница между двумя последовательными интервалами будет небольшой, вы сможете выйти из игры.
Это похоже на подход, используемый при поиске корней. Возможно, это излишество, поскольку размер шрифтов, приемлемый для отображения в конкретном приложении, скорее всего, будет довольно узким, а подход грубой силы, который вы уже используете, не отнимет много времени.