2012-12-20 7 views
5

Desidero disegnare i testi con Qt4.8, ma voglio anche mantenere la forma e la visibilità originali del font. Attualmente i contorni nascondono i caratteri del testo e li fanno apparire "più sottili" rispetto agli originali.Qt testo delineato senza diradamento font

Qt disegna il contorno dei caratteri di testo (e di altre forme) con QPen. QPen si sposta sul bordo effettivo di un carattere e dipinge all'esterno e all'interno della riga di bordo (vedere "Stile di giunzione" nel riferimento a QPen) all'interno di.

Se si utilizza una penna più spessa, un carattere di testo appare più sottile, mentre l'area totale rilevata dal carattere aumenta per il contorno. In altre parole, il contorno si erode nel carattere del testo.

Desidero che i caratteri di testo mantengano la loro forma e visibilità originali pur avendo "effetto alone" dal contorno. I.e., voglio dipingere solo l'esterno delle linee di bordo.

Qual è il modo più semplice per implementare tale effetto con Qt? Mi sono venute in mente alcune idee, ma mi chiedo se qualcuna di esse sia possibile.

piano A.

testi pareggio con contorno, quindi disegnare gli stessi testi senza contorno su quelli delineati.

Sfortunatamente, QTextCursor non supporta "overdrawing" o "overtyping", cosa che si può fare con le macchine da scrivere classiche. Ci sarebbe anche una penalità per le prestazioni.

Piano B.

modificare la libreria Qt in modo che trae contorno con QPen prima, poi riempire all'interno con QBrush. QBrush dipingerà sulla parte interna del contorno e lascerà intatto solo l'esterno.

Non sono sicuro se funziona e voglio evitare di modificare la libreria Qt se possibile.

Plan C.

Passare il "CompositionMode" del QPainter utilizzato per disegnare il testo a "QPainter :: CompositionMode_DestinationOver" temporaneamente.

Per fare ciò, penso di aver bisogno di controllare il QPainter privato e temporaneo creato e utilizzato dai widget di manipolazione del testo di Qt come QTextBrowser, ma non so come possa essere fatto.

Sono nuovo alla programmazione Qt e utilizzo Qt 4.8.2 su X Window.

È possibile visualizzare il problema aggiungendo le seguenti righe di codice (riga 156-164) a /usr/lib64/qt4/examples/richtext/calendar/mainwindow.cpp, compilandolo ed eseguendolo e aumentando la dimensione del carattere in 40 o più grande.

QTextCharFormat format = cursor.charFormat(); 
format.setFontPointSize(fontSize); 

QTextCharFormat boldFormat = format; 
boldFormat.setFontWeight(QFont::Bold); 

// Additional code lines for green outline : line 156 
QPen pen; 
pen.setStyle(Qt::SolidLine); 
pen.setWidthF(4); 
pen.setBrush(Qt::green); 
pen.setCapStyle(Qt::RoundCap); 
pen.setJoinStyle(Qt::RoundJoin); 
boldFormat.setTextOutline(pen); 
// The end of the additional code : line 164 

Se riesci a dirmi la strada da percorrere e a darmi gli indizi iniziali, apprezzerò molto il tuo aiuto.

+0

Grazie a Ian Atkin, ho esaminato l'esempio di "Painter Paths" e ho iniziato a pensare che i miei piani B e C fossero contrari al progetto fondamentale di Qt. Con la regola di riempimento "Dispari pari", dipingere solo all'esterno delle linee di bordo con QPen e riempire l'interno con QBrush produrrebbe un risultato sgradevole con l'esempio "a forma di stella" e "quadrato e cerchio sovrapposti". –

+0

@Tapa, ho lasciato questa domanda aperta per molto tempo e non ho avuto il tempo di rivederlo (ero stato sommerso da un altro progetto). Mi dispiace molto per la mia risposta ritardata. E, sì, uno dei miei colleghi ha risolto il problema con un modo abbastanza simile alla soluzione. Accetto la tua risposta come risposta alla mia domanda. Grazie mille. –

risposta

1

Ho trovato un modo, come fare tale delineazione per gli oggetti di testo QGraphicsView. Penso che tu possa usarlo per qualsiasi classe basata su QTextDocument (QTextEdit, per esempio).Ho creato una classe basata sulla QGraphicsTextItem e reimplementata la sua funzione di paint:

void paint (QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget) 
{ QTextCharFormat format; 
    format.setTextOutline (QPen (Qt::white, 3, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); // Color and width of outline 
    QTextCursor cursor (this->document()); 
    cursor.select (QTextCursor::Document); 
    cursor.mergeCharFormat (format); 
    QGraphicsTextItem::paint (painter, option, widget); 
    format.setTextOutline (QPen (Qt::transparent)); 
    cursor.mergeCharFormat (format); 
    QGraphicsTextItem::paint (painter, option, widget); 
} 

L'unico errore che ho notato per questa soluzione - quando si modifica il testo e iniziare a selezionare alcune lettere, si verifica il clipping. Ma è quasi impercettibile. Per gli elementi non modificabili non riesco a trovare alcun bug.

Ma se si vuole delineare QPushButton testo (ad esempio), allora è banale (questo problema è stato discusso molte volte) - all'interno reimplementato paintEvent creare QPainterPath, chiamare path.addText, quindi utilizzare painter.strokePath, painter.fillPath-strokePath crea contorno, e fillPath in primo piano.

Problemi correlati