2016-06-09 9 views
5

Jestem zobowiązany do tworzenia elementów tekstowych o dokładnej szerokości i wysokości zawartości tekstu.
Wysokość tekstu jest najważniejszym wymaganiem.
Pozycja tekstu powinna być względna względem samego tekstu.Ustaw treść tekstu QGraphicsTextItem o dokładnej wysokości i szerokości.

Muszę również umieć umieścić go na płótnie w dokładnym miejscu.

Założenie płótna (do wydrukowania) (na większym QGraphicsScene), powiedzmy, że 5-calowa szerokość i 1-calowa wysokość, mój tekst powinien być w stanie rozciągnąć górny-dolny-lewy-prawy - i być umieszczony na płótnie, a nie jako część rozstać się.


Jestem podkategorią QGraphicsTextItem dla mojego rodzaju przedmiotu. Zmieniam rozmiar, używając QTransform(), do wymaganego rozmiaru - w calach lub mm lub pikselach (72 * cala).
ustawienie także margines document() 0, i wszystko wewnątrz (jak QTextBlockFormat marginesy) również na 0.

I wdrożyliśmy setItemSize(QSizeF sz) (z sz w pikselach), które zmienia rozmiar QGraphicsTextItem wymagane.
Sz inicjalizowany jest za pomocą prostokąta prostokąta.
Założenie, że tekst nie jest zawijany, tekst jednoliniowy (tekst wieloliniowy może zostać rozwiązany osobno po rozwiązaniu tego problemu).

Podczas dodawania elementu do obszaru roboczego nadal widzę margines górny i dolny - i zależy to od wyboru czcionki.
Narysowałem prostokąt wokół przedmiotu, aby go zobaczyć.
Odległości góra/dół zależą od wyboru czcionki.


Próbowałem użyć parametrów czcionki, aby określić te dystanse (w paint() I zostały rysowania linii, aby spróbować ustalić pozycję i prostokąt, w którym tekst pasuje).

Byłbym szczęśliwy, mogąc przynajmniej móc określić prawidłowy rozmiar do użycia dla wielkich liter, bez akcentów lub znaków specjalnych czcionek (byłby to początek, choć naturalnie musiałbym móc używać dowolnych znaków).
Ale przynajmniej jakiś sposób do określenia rozmiaru i pozycję (w stosunku do (0,0) z pozycji) treści tekstu nawet w najprostszym przypadku .....

Metryki czcionek tightBoundingRect() wydaje najdokładniejszy pod względem wielkości, ale wydaje się niemożliwy do określenia jego położenie, aby w jakiś sposób poprawnie utworzyć moje elementy, i może zmienić rozmiar/przesunąć je poprawnie, aby zmieściły się na płótnie.


Oto kilka przykładów z mojej walce, aby określić przynajmniej dokładny rozmiar i położenie tekstu w stosunku do (0,0) elementu (przy założeniu, że kiedyś to zrobię, jestem w stanie narazić że info na zewnątrz lub uwzględnij przesunięcie w transformacji przedmiotu przy zmianie rozmiaru).
Zauważ, że rozmiar tekstu reklamowanego przez dane czcionki nie zawsze pokrywa się z tekstem, a dla różnych czcionek nie jestem w stanie ustawić ciasnego prostokąta otaczającego (magenta) wokół samego tekstu. (Zrobiłem wiele domysłów, poniższy kod to tylko jeden - linie próbują pokazać różne rozmiary metryk czcionki).

enter image description here

Powyższy były eksperymenty w funkcji malowania elementu tekstu dziedziczy 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(); 
} 

Ja również nie spróbował wykorzystać QGraphicsTextItem, ale farba tekst wewnątrz prostokąta. To samo się dzieje.

(Qt 4.7 - 5.x)

+0

Proszę podać zrzut ekranu, co widzisz i czego oczekujesz. Mam wrażenie, że walczysz ze wspinaczką lub czymś podobnym. –

+0

@MarekR - Dodałem moją funkcję do obliczania pozycji i zrzutów ekranu, w mojej odpowiedzi poniżej. – Thalia

Odpowiedz

2

nie jest dobrym rozwiązaniem. To jest próba rozwiązania mojego własnego problemu - w pierwszej iteracji - ustawienia tekstu o zadanej szerokości i wysokości za pomocą metryk czcionek.

Przyczyny nie są dobre -

  • Nawet po zmiany rozmiaru tekstu jest mniejsza niż pożądane, nie rozumiem dlaczego

  • Pozycja jest nieprawidłowa, na podstawie stylu czcionki Tekst może być powyżej lub poniżej płótna, co oznacza, że ​​zostanie obcięty.


zmienić rozmiar to przy użyciu współczynnika obliczonego z pozycji ograniczającej rect wielkości i parametrów czcionki obwiedni rect (użyłem napięty obwiedni rect dla bardziej dokładnego rozmiaru).

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; 

następnie ustawiając rozmiar:

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 

Funkcja na pozycję ustawiania: próbuje wyśrodkować tekst:

// 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); 

Poniższe zdjęcia są dla fontHeight = m_docHeight -

Pożądane :
- albo cały rozmiar tekstu (wynurzanie + zniżanie) to wysokość dokumentu, a tekst jest wyśrodkowany w pionie w oparciu o treść
- lub tekst o dużych rozmiarach jest równy wysokości dokumentu, a zejście jest poniżej dokumentu (tekst wyśrodkowany na podstawie tylko wielkich liter) - to wydaje się łatwiejsze w jaki QGraphicsTextItem wydaje się umieszczenie go

Actual:
- tekst jest mniejszy bez względu na to, jakie parametry mogę używać do skali i skupionego na podstawie górnej przypadku tekstu

enter image description here

jak przedstawiono powyżej - Ja h nie mam pojęcia, jak mógłbym wyśrodkować w pionie w oparciu o zawartość (tak dla tekstu od krawędzi do krawędzi, w którym zmieściłoby się pochodzenie) - i zamiast tego, wszystko, czego naprawdę chcę, to wielkie, duże litery, ale mogę ". Wydaje się, że są w stanie to osiągnąć.

Och i te są dla czcionki typu Arial - jeden z najlepiej zachowanych. Inne czcionki przeskakują w dowolne miejsce, nad lub pod płótnem.A w przypadku niektórych czcionek wynikowy tekst jest w rzeczywistości mniejszy - co jest dla mnie niewytłumaczalne, ponieważ w jaki sposób ciasny prostokąt ograniczający może być mniejszy niż prostokąt ograniczający element ...

Nadal jest tak daleko, jak to możliwe, aby uzyskać mój tekst zbliżony do "prawdziwego" rozmiaru i umieszczony na płótnie pasującym do jego rozmiaru.

+2

Spróbuj użyć 'QFontMetricsF' zamiast' QFontMetrics'. Od tego czasu miałem kilka koszmarów. – p4plus2

+0

@ p4plus2 - Wymieniłem go, ale nie widzę żadnej zmiany. – Thalia

Powiązane problemy