2016-06-09 8 views
5

텍스트 내용을 정확하게 작성하려면 폭과 높이가 인 인 텍스트 항목을 만들어야합니다.
텍스트의 높이가 가장 중요한 요구 사항입니다.
텍스트의 위치는 텍스트 자체에 상대적이어야합니다.
정확한 높이와 너비의 QGraphicsTextItem 텍스트 내용 설정

정확한 위치에 캔버스에 배치 할 수 있어야합니다.

너비가 5 인치이고 높이가 1 인치 인 (인쇄용) 캔버스를 사용한다고 가정하면 내 텍스트는 왼쪽 아래에서 왼쪽 아래까지 늘릴 수 있어야하고 일부는 아닌 캔버스에 배치해야합니다. 밖으로 나간다.


내 항목 유형에 대해 QGraphicsTextItem을 하위 분류하고 있습니다. QTransform()을 사용하여 필요한 크기 (인치 또는 mm 또는 픽셀 (72 * in))로 크기를 조정하고 있습니다.
또한 I는 필요에 따라이 setItemSize(QSizeF sz) (픽셀 SZ으로), 즉 QGraphicsTextItem 크기를 조절 구현 또한 0

에 내부 document() 0 마진 아무것도 (같은 QTextBlockFormat 마진)를 설정.
sz는 항목 경계 rect를 사용하여 초기화됩니다.
줄 바꿈이없는 것으로 가정하면 한 줄 텍스트 (이 문제가 해결되면 여러 줄을 개별적으로 해결할 수 있음).

항목을 캔버스에 추가 할 때 상단 및 하단 여백이 여전히 표시되며 글꼴 선택에 따라 다릅니다.
항목 주위에 직사각형을 그려 보았습니다.
위쪽/아래쪽 간격은 글꼴 선택에 따라 다릅니다.


나는 (텍스트가 맞는있는 위치와 사각형을 결정하려고 paint()에 내가 선을 그릴되었다)이 거리를 결정하는 글꼴 메트릭을 사용하려고했다.

적어도 대문자, 악센트 또는 특수 문자 글꼴에 사용할 올바른 크기를 결정할 수있어서 기쁠 것입니다. (자연스럽지 만 어떤 문자도 사용할 수 있어야합니다).
그러나 적어도 몇 가지 방법은 tightBoundingRect() 보인다

글꼴 메트릭 ..... 심지어 간단한 경우에 텍스트 내용의 (항목)를 (0, 0을 기준으로) 크기와 위치를 결정하는 크기에 대해 가장 정확하지만 위치를 결정하는 것이 불가능 해 보이므로 필자는 올바르게 항목을 만들고 어쩌면 캔버스에 맞게 크기를 조정하거나 바꿀 수 있습니다. 여기


적어도 항목의 (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(); 
} 

하지만, 사각형 내부 페인트 텍스트 :

enter image description here

QGraphicsTextItem을 상속 텍스트 항목의 페인트 기능의 실험이었다. 같은 일이 일어난다.

(Qt는 4.7 - 5.x를)

+0

귀하가보고있는 것과 기대하고있는 것을 스크린 샷으로 제공해주십시오. 나는 당신이 등반이나 비슷한 것을 가지고 싸우고 있다고 느끼고 있습니다. –

+0

@MarekR - 위치 및 화면 샷 계산에 대한 내 기능을 아래의 답에서 추가했습니다. – Thalia

답변

2

이 좋은 해결책이 아니다. 이것은 글꼴 메트릭스를 사용하여 주어진 너비와 높이로 텍스트를 설정하는 첫 번째 반복에서 내 자신의 문제를 해결하기위한 시도입니다. 좋은으로하지 않는

이유 -

  • 후에도 크기를 조정, 텍스트, 이해가 안 원하는 것보다 작은 이유

  • 위치는 글꼴 스타일 텍스트 수에 따라, 잘못 캔버스 위 또는 아래에 있어야합니다.


가 나는 RECT 크기와 RECT 경계 폰트 메트릭스 (나는 더 정확한 크기에 대한 엄격한 경계 RECT를 사용) 경계 항목에서 계산 된 계수를 사용하여 크기를 조정합니다.
myText->setItemFontSize(12); // If I use font metrics I need to reset text size on every change, because resizing loses font info 
QFontMetricsF fm(myText->font()); 
QRectF fmRect = fm.tightBoundingRect(myText.toPlainText().toUpper()); 
// without toUpper() the size is too small - even so it is a bit small 
// I read tightBoundingRect is slow - but boundingRect and height and ascent all give values that result in even smaller size 
//qreal absH = fm.ascent(); 
qreal absH = fmRect.height(); 
qreal absW = fmRect.width(); 
qreal absHeightRatio = myText->getItemSize().height()/absH; 
qreal absWidthRatio = myText->getItemSize().width()/absW; 

다음 설정 크기 :

myText->setItemSize(QSizeF(absWidthRatio * textLength, absHeightRatio * fontHeight)); 
// This function scales the `QTransform` on item 
// but since I request a final position dependent on item size 
// (including blank space around it) - it has no chance of being accurate..... 
// This is where my next effort will go, figuring out how to get rid of the fluff 
// around the item inside the scaling 

위치를 설정하는 기능 : 아래

// leftShift = 10, rightShift = 10 in example 
myText->setPos(0,0); 
QRectF r = myText->mapToScene(myText->boundingRect()).boundingRect(); 
QSizeF sz = r.size(); 
qreal w = sz.width(); 
qreal h = sz.height(); 
qreal cx = (m_docLength - w + leftShift - rightShift)/2 - r.left(); 
qreal cy = (m_docHeight - h)/2 - r.top(); 
myText->setPos(cx, cy); 

이미지는 = m_docHeight fontHeight위한 -

바람직한 : 텍스트를 중앙에 노력 :
- 전체 텍스트 크기 (상승 + 하강)은 문서 높이와 같고 텍스트는 내용에 따라 세로로 가운데에 배치됩니다.
- 대문자 크기 텍스트는 문서 높이와 같고 강하는 문서 아래입니다 (대문자 만 중심으로 텍스트 중심). 에 QGraphicsTextItem

실제 위치를 보인다 방법 :
이 - 텍스트 작은 아무리 내가 규모에 사용하고, 위와 같이 대문자 텍스트

enter image description here

을 기반으로 중심 매개하는 - 나 ave 내가 컨텐트를 기반으로 세로로 중심을 잡을 수있는 방법에 대한 아이디어가 없습니다. (따라서 가장자리에서 가장자리까지의 텍스트에 대해서 강하가 들어 맞을 것입니다.) 그리고 대신에 내가 원하는 것은 가장자리 대문자입니다. 그것을 성취 할 수있을 것 같습니다.

아 이들 글꼴은 굴림 글꼴입니다. 가장 잘 작동하는 글꼴 중 하나입니다. 캔버스의 위나 아래에 다른 글꼴이 점재합니다.그리고 일부 글꼴의 경우 결과 텍스트가 실제로 더 작습니다. 그 이유는 좁은 경계 사각형을 항목 경계 사각형보다 작게 만들 수 있기 때문입니다.

그래도 이것이 내 텍스트를 "참"크기에 가깝게 배치하고 크기와 일치하는 캔버스에 배치합니다.

+2

'QFontMetrics' 대신'QFontMetricsF'를 사용해보십시오. 나는이 일로부터 몇 가지 악몽을 꿨다. – p4plus2

+0

@ p4plus2 - 교체했지만 변경 사항이 없습니다. – Thalia