テキスト コンテンツの正確な幅と高さでテキスト アイテムを作成する必要があります。
テキストの高さは最も重要な要件です。
テキストの位置は、テキスト自体に対して相対的でなければなりません。
また、キャンバス上の正確な場所に配置できる必要があります。
(印刷可能な)キャンバス(より大きなQGraphicsScene
)、たとえば幅5インチ、高さ1インチと仮定すると、テキストは上下左右に引き伸ばされ、部分的にではなくキャンバスに配置されるはずです。
QGraphicsTextItem
アイテム タイプのサブクラス化を行っています。を使用してQTransform()
、必要なサイズ (インチ、mm、またはピクセル (72 * インチ)) にサイズ変更しています。
また、document()
マージンを 0 に設定し、内部 (QTextBlockFormat
マージンなど) もすべて 0 に設定します。
setItemSize(QSizeF sz)
必要に応じてサイズを変更する(ピクセル単位のsz)を実装しましたQGraphicsTextItem
。
sz はアイテムのバウンディング rect を使用して初期化されます。
折り返されていないと仮定すると、1 行のテキスト (この問題が解決されれば、複数行のテキストは個別に解決される可能性があります)。
項目をキャンバスに追加すると、まだ上下の余白が表示されますが、これはフォントの選択によって異なります。
アイテムを表示するために、アイテムの周りに四角形を描きました。
上/下の距離は、フォントの選択によって異なります。
これらの距離を決定するためにフォント メトリックを使用しようとしましpaint()
た (テキストが収まる位置と四角形を決定するために線を引いています)。
少なくとも、大文字、アクセントまたは特殊文字のフォントに使用する正しいサイズを決定できれば幸いです(もちろん、任意の文字を使用できる必要がありますが、それは出発点です)。しかし、最も単純なケースであっても、テキストコンテンツのサイズと位置(アイテムの (0,0) に相対的)
を決定する少なくとも何らかの方法.....
フォント メトリックtightBoundingRect()
はサイズに関して最も正確に見えますが、その位置を特定することは不可能であるため、どうにかしてアイテムを正しく作成し、キャンバスに収まるように正しくサイズ変更/シフトすることができます。
アイテムの (0,0) に対するテキストの少なくとも正確なサイズと位置を決定するのに苦労した例をいくつか示します (これを行うと、その情報を外部に公開するか、シフトを含めることができると仮定します)。サイズ変更時にアイテムが変換されます)。
フォント メトリックによってアドバタイズされるテキストのサイズが常にテキストをカバーするとは限らないことに注意してください。また、フォントが異なると、テキスト自体の周りにタイトな境界四角形 (マゼンタ) を配置することができません。(複数の推測を行いました。以下のコードは 1 つにすぎません。行はさまざまなフォント メトリック サイズを表示しようとしています)。
上記は、テキストアイテム継承のペイント機能の実験でした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)