| ホーム · All Namespaces · 全てのクラス · 主要なクラス · グループ別クラス · Modules · 関数一覧 |
[前へ: Arthur 描画システム] [ホーム] [次へ: Qt 4 メインウィンドウクラス]
Scribe は Qt 4 におけるテキストレイアウトクラスである. Qt 3 で導入された古いリッチテキストエンジンを置き換え、プレインテキストとリッチテキストの両方において、テキスト処理とレイアウトに関する新しい機能を提供する.
Scribe クラスの使用に関する詳細については、 リッチテキスト処理 のドキュメントを参照のこと.
Qt 4 でのテキストレンダリングとレイアウトのサポートは、テキストコンテンツを Qt 3 よりも柔軟に表現できるよう、全体に渡る再設計がおこなわれた. また、 Qt 4 ではドキュメントの編集に関するより便利なプログラミングインターフェースが用意された. これらの改良は既存のテキストレンダリングエンジンを再実装し、いくつかの新しいクラスを追加することによって実現されている.
以下のセクションでは、Scribe のコンセプトについて概説する.
テキストドキュメントは QString オブジェクトではなく、QTextDocument クラスによって表現される. ( QTextDocument 、 QString )。 個々の QTextDocument オブジェクトには、ドキュメントの内部表現、その構造、アンドゥ/リドゥを実現するための更新履歴に関する情報が含まれる. 本アプローチでは、レイアウト管理のような機能は専門のクラスに委託することで、フレームワークに重点を置いたものとなっている.
ドキュメントは外部のソースから変換されるか、または Qt によって一から生成される. 生成の手順としては、 QTextEditのような編集ウィジェットを用いるか、 Scribe API を明示的に呼び出すことでおこなう.
Text documentは相補的な二通りの方法でアクセスできる. 一つはeditorで用いるlinear bufferとしてアクセス,もう一つは,layout enginで用いるobjectの階層構造によるアクセス方法である. 階層構造を持つdocument modelでは一般的にobjectはframe,table,listといった視覚的要素に対応する. より下位レベルにおいては, text styleやalignmentといったpropertyに対応する. documentのリニア表現は、documentの内容を編集したり、操作したりする場合に使用される.
ドキュメントはそれぞれルートフレームを持ち、その中に他の構造要素が含まれる. 構造要素としては、テーブル、テキストブロック、および他のフレームを挙げることができ、好きなだけ入れ子にして使うことができる.
フレームはドキュメントを論理的に区分して、レンダリングする際の表示方法に関するプロパティを指定できる. テーブルはフレームの一種であるが、縦横に並んだ複数のセルからなり、その中にさらに他の構造やテキストを入れることができる仕組みを持っている. テーブルはセルを柔軟に設定し、レイアウトをおこなうことができる.
Text blockは,textの各部分について,textと文字のformatに関する情報を管理する. Text関連のpropertyは,文字のレベルとブロックのレベルの双方で定義される. 文字レベルにおいては,fontの種類やTextの色, font weightといったpropertyが指定される. ブロックレベルのpropertyでは,textの記述方向やアライメント,背景色といった,より高いレベルにおけるtextの表示方法や振る舞いについてコントロールする.
ドキュメント構造は直接操作する性格のものではなく、編集はカーソルベースのインターフェースを用いておこなう.
ドキュメントは QTextCursor クラスのインタフェースを使って編集できる. カーソルはコンストラクタを使って生成するか,エディタウィジェットのものを利用できる.カーソルによって,ユーザがエディタ上で編集するのと全く同じ編集操作を行える.結果,ドキュメント構造の情報はカーソルを通じて利用可能であり,,変更を加えることができる. 編集の際にカーソル指向のインタフェースを利用することで編集の操作が判りやすくなり,開発者がカスタムエディタを書くプロセスがより簡単になる.
QTextCursor クラスは、ドキュメントの中で選択されたテキストに関する情報を取り扱うこともでき、同様にユーザがエディタ上にてテキストを選択した際のアクションに概念的に似たモデルに従っている.
ドキュメントのレイアウトは、デバイスへ表示する際やドキュメントの視覚表示に関する情報が要求された場合に初めて意味を持つ. 逆にいえば、こうした状況が発生しない限り、ドキュメントが整形される必要は生じない.
ドキュメントのレイアウトは、 QAbstractTextDocumentLayout class. This class provides a common interface for layout and rendering engines. The default rendering behavior is currently implemented in a private class. This approach makes it possible to create custom layouts, and provides the mechanism used when preparing pages for printing or exporting to Portable Document Format (PDF) files.
ここでは、Scribe クラスに関する 2つの異なる利用方法を示す. 1つは、リッチテキストの生成と操作に関するもの. もう1つは、プレインテキストのレイアウトに関するものである.
リッチテキストを含んだドキュメントは、外部ソースの HTML をインポートするか、 QTextCursorを使って生成できる. リッチテキストドキュメントを簡単に扱うには、 QTextEdit クラスを用いるのがよい. 以下のコードは HTML をインポートし、テキストエディットウィジェットを用いて表示するものである.
QTextEdit *editor = new QTextEdit(parent);
editor->setHtml(aStringContainingHTMLtext);
editor->show();
テキストエディットからドキュメントを取り出すには document() 関数を用いる. 取り出したドキュメントは、 QTextCursor クラスを使ってプログラム的に変更を加えることができる. このクラスはスクリーン上のカーソルにならって設計されており、同じ感覚で編集操作を行うことができる. 以下のコードではドキュメントの先頭行を太字に変え、その他のフォントプロパティは弄らない. ドキュメントに変更が加えられると、エディタは自動的に更新される.
QTextDocument *document = edit->document();
QTextCursor cursor(document);
cursor.movePosition(QTextCursor::Start);
cursor.movePosition(QTextCursor::EndOfLine, QTextCursor::KeepAnchor);
QTextCharFormat format;
format.setFontWeight(QFont::Bold);
cursor.mergeCharFormat(format);
Note that the cursor was moved from the start of the first line to the end, but that it retained an anchor at the start of the line. This demonstrates the cursor-based selection facilities of the QTextCursor class.
Rich text can be generated very quickly using the cursor-based approach. The following example shows a simple calendar in a QTextEdit widget with bold headers for the days of the week:
editor = new QTextEdit(this);
QTextCursor cursor(editor->textCursor());
cursor.movePosition(QTextCursor::Start);
QTextCharFormat format(cursor.charFormat());
format.setFontFamily("Courier");
QTextCharFormat boldFormat = format;
boldFormat.setFontWeight(QFont::Bold);
cursor.insertBlock();
cursor.insertText(" ", boldFormat);
QDate date = QDate::currentDate();
int year = date.year(), month = date.month();
for (int weekDay = 1; weekDay <= 7; ++weekDay) {
cursor.insertText(QString("%1 ").arg(QDate::shortDayName(weekDay), 3),
boldFormat);
}
cursor.insertBlock();
cursor.insertText(" ", format);
for (int column = 1; column < QDate(year, month, 1).dayOfWeek(); ++column) {
cursor.insertText(" ", format);
}
for (int day = 1; day <= date.daysInMonth(); ++day) {
int weekDay = QDate(year, month, day).dayOfWeek();
if (QDate(year, month, day) == date)
cursor.insertText(QString("%1 ").arg(day, 3), boldFormat);
else
cursor.insertText(QString("%1 ").arg(day, 3), format);
if (weekDay == 7) {
cursor.insertBlock();
cursor.insertText(" ", format);
}
}
The above example demonstrates how simple it is to quickly generate new rich text documents using a minimum amount of code. Although we have generated a crude fixed-pitch calendar to avoid quoting too much code, Scribe provides much more sophisticated layout and formatting features.
Sometimes it is important to be able to format plain text within an irregularly-shaped region, perhaps when rendering a custom widget, for example. Scribe provides generic features, such as those provided by the QTextLayout class, to help developers perform word-wrapping and layout tasks without the need to create a document first.
プレインテキストのパラグラフを整形し、書き起こすのは何ら難しいことではない. 以下の例では、テキストのパラグラフを単一のフォントで、円の右側に沿うようにレイアウトするものである.
QTextLayout textLayout(text, font); qreal margin = 10; qreal radius = qMin(width()/2.0, height()/2.0) - margin; QFontMetrics fm(font); qreal lineHeight = fm.height(); qreal y = 0; textLayout.beginLayout(); while (1) { // create a new line QTextLine line = textLayout.createLine(); if (!line.isValid()) break; qreal x1 = qMax(0.0, pow(pow(radius,2)-pow(radius-y,2), 0.5)); qreal x2 = qMax(0.0, pow(pow(radius,2)-pow(radius-(y+lineHeight),2), 0.5)); qreal x = qMax(x1, x2) + margin; qreal lineWidth = (width() - margin) - x; line.setLineWidth(lineWidth); line.setPosition(QPointF(x, margin+y)); y += line.height(); } textLayout.endLayout(); QPainter painter; painter.begin(this); painter.setRenderHint(QPainter::Antialiasing); painter.fillRect(rect(), Qt::white); painter.setBrush(QBrush(Qt::black)); painter.setPen(QPen(Qt::black)); textLayout.draw(&painter, QPoint(0,0)); painter.setBrush(QBrush(QColor("#a6ce39"))); painter.setPen(QPen(Qt::black)); painter.drawEllipse(QRectF(-radius, margin, 2*radius, 2*radius)); painter.end();
まず、表示したいテキストの文字列と使用したいフォントを指定してテキストレイアウトを作成する. 次に、テキストのフォーマットからテキストラインを求め、利用可能なスペースを使ってテキストの折り返しをおこなうことで、テキストが正しく整形されるようにしている. ラインはページの下方向へと配置されていく.
整形されたテキストはペイントデバイスに書き出すことができる. 上記のコードでは、テキストは直接ウィジェットに書かれる.
The layout system used to display rich text documents also supports paged layout of documents, and this is used by Qt to generate output for printing. The printing process is performed by QPrinter and controlled by the user via options displayed in a QPrintDialog:
QTextDocument *document = editor->document();
QPrinter printer;
QPrintDialog *dlg = new QPrintDialog(&printer, this);
if (dlg->exec() != QDialog::Accepted)
return;
document->print(&printer);
Rich text documents can also be exported as PDF files using QPrinter and the appropriate print engine:
QString fileName = QFileDialog::getSaveFileName(this, "Export PDF",
QString(), "*.pdf");
if (!fileName.isEmpty()) {
if (QFileInfo(fileName).suffix().isEmpty())
fileName.append(".pdf");
QPrinter printer(QPrinter::HighResolution);
printer.setOutputFormat(QPrinter::PdfFormat);
printer.setOutputFileName(fileName);
textEdit->document()->print(&printer);
}
構造化ドキュメントモデルと連携動作するカーソルベースの編集機能は、リッチテキスト文書の取り扱いと表示に関する強力なツールであり、Qt 3 の API では利用できなかった機能である. 使用されているエンジンは完全に書き直されたもので、Qt 3 のリッチテキストエンジンは使われていない.
Qt 4 における QTextEdit は API から完全に書き直されており、Qt 3 とは全く別物となっているが、互換性のあるメソッドがいくつか用意されており、基本的には Qt 3 の利用者にとって親しみやすい方法でウィジェットが利用できるようになっている. このクラスは新しい API を使ったエディタウィジェットの実例でもあり、 QTextCursor をベースとして文書エディタがきちんと実装できることを示している.
[前へ: Arthur 描画システム] [ホーム] [Next: Qt 4 メインウィンドウクラス]
| Copyright © 2008 Nokia | Trademarks | Qt 4.4.3 |