6

Qt4.8で白抜き文字を描きたいけど、フォントの形や見やすさはそのままにしたい。現在、アウトラインはテキスト文字を隠し、オリジナルよりも「細く」見えます。

Qt は、QPen を使用してテキスト文字 (およびその他の形状) の輪郭を描画します。QPen は文字の実際のエッジ上を移動し、エッジ ラインの外側と内側をペイントします (QPen リファレンスの「結合スタイル」を参照してください)。

太いペンを使用すると、テキスト文字は細く見えますが、文字が占める総面積はアウトラインのために増加します。つまり、アウトラインがテキスト文字に浸食されます。

アウトラインによる「ハロー効果」を持ちながら、テキスト文字の元の形状と可視性を維持したいと考えています。つまり、エッジラインの外側だけを塗りたいのです。

Qtでそのような効果を実装する最も簡単な方法は何ですか? いくつかアイデアを思いつきましたが、どれも可能ではないでしょうか。

プランA。

アウトライン付きのテキストを描画し、アウトライン化されたテキストの上にアウトラインなしで同じテキストを描画します。

残念ながら、QTextCursor は、従来のタイプライターで実行できる「オーバードロー」または「オーバータイピング」をサポートしていません。パフォーマンスのペナルティもあります。

次の手段。

まず QPen でアウトラインを描画し、次に QBrush で塗りつぶすように Qt ライブラリを変更します。QBrush はアウトラインの内側部分をペイントし、外側だけをそのまま残します。

うまくいくかどうかわからないので、可能であれば Qt ライブラリの変更は避けたいと思っています。

プランC。

テキストの描画に使用する QPainter の「CompositionMode」を一時的に「QPainter::CompositionMode_DestinationOver」に切り替えます。

これを行うには、QTextBrowser などの Qt のテキスト操作ウィジェットによって作成および使用されるプライベートおよび一時的な QPainter を制御する必要があると思いますが、それを行う方法がわかりません。

Qt プログラミングは初めてで、X ウィンドウで Qt 4.8.2 を使用しています。

次のコード行 (行 156-164) を /usr/lib64/qt4/examples/richtext/calendar/mainwindow.cpp に追加し、コンパイルして実行し、フォント サイズを 40 以上に大きくすると、私の問題を確認できます。

 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

道順と最初の手がかりを教えていただければ、大変助かります。

4

1 に答える 1

2

QGraphicsView私は、テキスト オブジェクトに対してそのようなアウトラインを作成する方法を見つけました。QTextDocumentQTextEditたとえば)に基づく任意のクラスに使用できると思います。その機能に基づいてクラスを作成しQGraphicsTextItem、再実装しました。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);
}

このソリューションで気付いた唯一のバグは、テキストを編集して文字を選択し始めると、クリッピングが発生することです。でもほとんど目立たない。編集不可能なアイテムについては、バグが見つかりません。

しかし、テキストのアウトラインを作成したい場合QPushButton(たとえば)、それは些細なことです (この問題は何度も議論されています) - 内部で再実装されたpaintEventcreate QPainterPath、 call path.addText、次に use painter.strokePath, painter.fillPath-strokePathアウトラインを作成し、fillPath前景を塗りつぶします。

于 2013-07-07T23:39:29.580 に答える