Мне нужно создать текстовые элементы с точной шириной и высотой текстового содержимого.
Высота текста является наиболее важным требованием.
Положение текста должно быть относительно сам текст.
Я также должен быть в состоянии разместить его на холсте в точном месте.
Предполагая (пригодный для печати) холст (на большем QGraphicsScene
), скажем, 5 дюймов в ширину и 1 дюйм в высоту, мой текст должен иметь возможность растягиваться сверху-снизу-влево-вправо - и быть помещенным на холст, а не часть в часть.
Я создаю подкласс QGraphicsTextItem
для своего типа элемента. Я изменяю его размер, используя QTransform()
, до требуемого размера - в дюймах, мм или пикселях (72*дюйма).
Также устанавливаю поле document()
равным 0, а все внутри (например, поля QTextBlockFormat
) также равным 0.
Я реализовал setItemSize(QSizeF sz)
(с sz в пикселях), который изменяет размер QGraphicsTextItem
по мере необходимости.
sz инициализируется с использованием прямоугольника, ограничивающего элемент.
Предполагая отсутствие переноса, однострочный текст (многострочный может быть решен отдельно как только этот вопрос будет решен).
При добавлении элемента на холст я по-прежнему вижу верхнее и нижнее поля, и они различаются в зависимости от выбора шрифта.
Я нарисовал прямоугольник вокруг элемента, чтобы увидеть его.
Расстояние между верхом и низом зависит от выбора шрифта. .
Я попытался использовать метрики шрифта для определения этих расстояний (в paint()
я рисовал линии, чтобы попытаться определить положение и прямоугольник, в который помещается текст).
Я был бы рад, по крайней мере, иметь возможность определить правильный размер для использования в верхнем регистре, без шрифтов с диакритическими знаками или специальными символами (это было бы началом, хотя, естественно, мне нужно было бы иметь возможность использовать любые символы).
Но по крайней мере, какой-то способ определить размер и позиция (относительно (0,0) элемента) текстового содержимого даже в самом простом случае.....
Метрика шрифта tightBoundingRect()
кажется наиболее точной по размеру, но кажется невозможным определить ее положение, чтобы я мог как-то правильно создавать свои элементы и, возможно, правильно изменять размер/смещать их, чтобы они поместились на холсте.
Вот несколько примеров моей борьбы за определение хотя бы точного размера и положения текста относительно (0,0) элемента (при условии, что как только я это сделаю, я смогу открыть эту информацию снаружи или включить сдвиг в элементе преобразуется при изменении размера).
Обратите внимание, что размер текста, рекламируемый метриками шрифта, не всегда покрывает текст, и для разных шрифтов я не могу расположить узкий ограничивающий прямоугольник (пурпурный) вокруг самого текста. . (Я сделал несколько предположений, приведенный ниже код только один - строки пытаются показать разные размеры метрик шрифта).
Выше были эксперименты с функцией рисования текстового элемента, наследующего QGraphicsTextItem
:
void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
{
// draw text
QGraphicsTextItem::paint(painter, option, widget);
QPen p;
p.setWidthF(0);
QFontMetricsF fm(this->font());
qreal ascent = fm.ascent(),
descent = fm.descent(),
hheight = fm.height();
QRectF r = QGraphicsTextItem::boundingRect();
QRectF rFont= fm.tightBoundingRect(toPlainText());
qreal xmax = r.right();
painter->save();
painter->setBrush(Qt::NoBrush);
// where is "ascent + descent"
p.setColor(Qt::green);
painter->setPen(p);
painter->drawLine(QPointF(2, ascent), QPointF(2, ascent + descent));
painter->drawLine(QPointF(2, ascent + descent), QPointF(xmax/2, ascent + descent));
// where is "height"
p.setColor(Qt::red);
painter->setPen(p);
painter->drawLine(QPointF(xmax/2, 0), QPointF(xmax/2, hheight));
painter->drawLine(QPointF(xmax/2, ascent + descent), QPointF(xmax, ascent + descent));
// where is "ascent"
p.setColor(Qt::yellow);
painter->setPen(p);
painter->drawLine(QPointF(6, 0), QPointF(6, ascent));
painter->drawLine(QPointF(6, ascent), QPointF(xmax, ascent));
// something that may look like top of the text
p.setColor(Qt::blue);
painter->setPen(p);
qreal yyy = ascent + rFont.y() + 1;
painter->drawLine(QPointF(5, yyy), QPointF(xmax, yyy));
// this should be useful... should be the natural offset
qreal yoffset = (r.height() - rFont.height()) / 2;
// qDebug() << yoffset << r << rFont;
//qreal y0 = (r.height() - fm.height())/2;
p.setColor(Qt::darkGreen);
painter->drawEllipse(10, yoffset, 1, 1);
// where is the font rect
p.setColor(Qt::magenta);
painter->setPen(p);
yoffset = (r.height() + rFont.height()) / 2;
painter->translate(0, yoffset);
painter->drawRect(rFont);
painter->restore();
}
Я также пробовал не использовать QGraphicsTextItem
, а рисовать текст внутри прямоугольника. То же самое происходит.
(Qt 4.7 - 5.x)