Rich Text Processing富文本处理

Scribe框架提供一系列读和控制富文本文档的类。Qt4提供像QTextDocument类,他能够为开发提供创建和修改结构的富文本文档。

文档内的信息通过两个补充的接口存取:

1. 基于光标的接口用来编辑。2. 可读的分层接口它提供文档结构的高层次预览。使用前者的优点是他可以使用操纵符编辑,提供了一个很好的用户交互接口,不会损失潜在的文档结构。而后者的接口在查询和文档展示时最有用。

帮助文档分为了六个章节来介绍Rich Text Processing,可以仔细查阅:

Rich Text Document Structure

The QTextCursor Interface

Document Layouts

Common Rich Text Editing Tasks

Advanced Rich Text Processing

Supported HTML Subset

 

Rich Text Document Structure

QTextDocument类是文本文档的代表,它包含了构建富文本文档所需的信息。文档的结构是由分层的文本块(text blocks),framestables和一些其他的内容对象组成。新元素的创建和插入可以使用QTextCursor或者editor widget(例如QTextEdit)。如下图表示了他们的分层结构:

Rich Text Processing富文本处理_第1张图片

 

使用QTextEdit使展示编辑富文本非常容易,文档可以为任何编辑部件无关地创建,例如:

        QTextDocument *newDocument = new QTextDocument;

也可以为已存在的编辑部件创建:

        QTextEdit *editor = new QTextEdit;

        QTextDocument *editorDocument = editor->document();

一个空文档包含一个root frame,这个root frame自己是包含一个空text block的。Frame不仅有分隔文档的功能,也有提供如何显示的功能。下面是获得root frame的方法:

        QTextDocument *textDocument;

        QTextFrame *root = textDocument->rootFrame();

Tableframe的专门类型,由一些单位(cells)组成,它们被安排成行和列,每一个都包含结构和文本。Table提供管理和呈现的特征,这样可以灵活的创建单位。Text blocks包含特殊化的文本和字符格式信息,例如字符的颜色,对齐,背景等等。以上的元素对应的类是QTextFrame, QTextTable, QTextBlock, (还有一个对应列表的类QTextList)。图片元素由特殊的text block代表。一组元素可以一起子类化为QTextBlockGroupQTextBlockGroupQTextFrame子类。

Text blocks可以通过QTextBlock::iterator遍历块的内部结构:

        QTextBlock::iterator it;

        for (it = currentBlock.begin(); !(it.atEnd()); ++it) {

            QTextFragment currentFragment = it.fragment();

            if (currentFragment.isValid())

                processFragment(currentFragment);

        }

QTextBlock提供了比较操纵符:== != <用来判断两个块是否相同,出现的先后。

Text frames可以由一组块和子frames组成。所有的frame除了root frame,都有父frame。使用QTextFrame::iterator遍历frame的子元素:

        QDomElement frameElement = ...

        QTextFrame::iterator it;

        for (it = frame->begin(); !(it.atEnd()); ++it) {

            QTextFrame *childFrame = it.currentFrame();

            QTextBlock childBlock = it.currentBlock();

            if (childFrame)

                processFrame(frameElement, childFrame);

            else if (childBlock.isValid())

                processBlock(frameElement, childBlock);

        }

QTextTableQTextFrame的子类,所以tables可以像对待QTextFrame一样对待。它每一个单位(cell)的检查可以通过行列号:

        for (int row = 0; row < table->rows(); ++row) {

            for (int column = 0; column < table->columns(); ++column) {

                QTextTableCell tableCell = table->cellAt(row, column);

                processTableCell(tableCell);

            }

        }

QTextListQTextBlockGroup的子类,它可以使用索引获得QTextList对象的项。

        for (int index = 0; index < list->count(); ++index) {

            QTextBlock listItem = list->item(index);

            processListItem(listItem);

        }

ImagesQTextDocument中由text fragment代表,由光标(cursor)接口创建,可以被字符格式修改:

        if (fragment.isValid()) {

            QTextImageFormat newImageFormat = fragment.charFormat().toImageFormat();

            if (newImageFormat.isValid()) {

                newImageFormat.setName(":/images/newimage.png");

                QTextCursor helper = cursor;

                helper.setPosition(fragment.position());

                helper.setPosition(fragment.position() + fragment.length(), QTextCursor::KeepAnchor);

                helper.setCharFormat(newImageFormat);

            }

        }

 

The QTextCursor Interface

文档可以通过QTextCursor提供的接口编辑,

使用cursor主要是用来插入或修改块中的文本,我们可以在编辑器中使用:

        QTextEdit *editor = new QTextEdit();

        QTextCursor cursor(editor->textCursor());

也可以直接从一个文档中获取。

        QTextDocument *document = new QTextDocument(editor);

        QTextCursor cursor(document);

一系列的编辑操作可以打包到一起去,这样可以使用beginEditBlock(),endEditBlock()实现,下面代码示例:

        cursor.beginEditBlock();

        cursor.movePosition(QTextCursor::StartOfWord);

        cursor.movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor);

        cursor.endEditBlock();

QTextCursor提供一些插入文档元素的操作:

    insertBlock()

    insertFrament()

    insertImage()

insertText()

以上都不会返回插入元素,下面的操作会返回插入的元素:

    insertFrame()

    insertList()

    insertTable()

一下是一些示例:

     // insert Text

     cursor.insertText(tr("Character formats"),

                       headingFormat);

     cursor.insertBlock();

     cursor.insertText(tr("Text can be displayed in a variety of " "different character formats. "), plainFormat); // 以某格式插入文本

     cursor.insertText(tr("We can emphasize text by "));

     cursor.insertText(tr("making it italic"), emphasisFormat);

     // insert block

     QTextBlockFormat backgroundFormat = blockFormat;

     backgroundFormat.setBackground(QColor("lightGray"));

     cursor.setBlockFormat(backgroundFormat);

     

     // insert frame

     QTextFrame *mainFrame = cursor.currentFrame();

     cursor.insertText(...);

     // 为子frame建立一个frame格式

     QTextFrameFormat frameFormat;

     frameFormat.setMargin(32);

     frameFormat.setPadding(8);

     frameFormat.setBorder(4);

QTextFrameFormat的格式示意图:

Rich Text Processing富文本处理_第2张图片

     cursor.insertFrame(frameFormat);

     cursor.insertText(...);

插入table

     QTextCursor cursor(editor->textCursor());

     QTextTable *table = cursor.insertTable(rows, columns, tableFormat);

它也可以定义格式:

     QTextTableFormat tableFormat;

     tableFormat.setBackground(QColor("#e0e0e0"));

     QVector<QTextLength> constraints;

     constraints << QTextLength(QTextLength::PercentageLength, 16);

     constraints << QTextLength(QTextLength::PercentageLength, 28);

     constraints << QTextLength(QTextLength::PercentageLength, 28);

     constraints << QTextLength(QTextLength::PercentageLength, 28);

     tableFormat.setColumnWidthConstraints(constraints);

     QTextTable *table = cursor.insertTable(rows, columns, tableFormat);

插入list

     QTextListFormat listFormat;

     if (list) {

         listFormat = list->format();

         listFormat.setIndent(listFormat.indent() + 1);

     }

     listFormat.setStyle(QTextListFormat::ListDisc);

     cursor.insertList(listFormat);

插入images:

     QTextImageFormat imageFormat;

     imageFormat.setName(":/images/advert.png");

     cursor.insertImage(imageFormat);:

 

Document Layouts

每个文档的布局都是子类化的QAbstractTextDocumentLayout类。QTextLayout可以帮助开发者呈现渲染文本,它可以用在plainrich textQTextLineQTextLayout内的一排文本,可以QTextLayout::createLine()创建。

下面是个例子:

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

 

Common Rich Text Editing Tasks

我们通常用QTextBrowserQTextEdit完成富文本编辑任务,通过QTextDocument创建文档,QTextCursor编辑,用文档结构展示。

例如利用文本编辑器部件展示HTML

     QTextEdit *editor = new QTextEdit(parent);

     editor->setHtml(aStringContainingHTMLtext);

     editor->show();

默认情况下,文本编辑器包含一个带有root frame的文档,可以editor->document()获得,可使用editor->textCursor()获得编辑器的光标QTextCursor

选择文本,通过移动光标,例如:QTextCursor::MoveMode(MoveAnchor, KeepAnchor)

     cursor.movePosition(QTextCursor::StartOfWord);

     cursor.movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor);

查找文本,下面是查找一个单词,并改变它的颜色以显示:

     QTextCursor newCursor(document);

     while (!newCursor.isNull() && !newCursor.atEnd()) {

         newCursor = document->find(searchString, newCursor);

         if (!newCursor.isNull()) {

             newCursor.movePosition(QTextCursor::WordRight,

                                    QTextCursor::KeepAnchor);

             newCursor.mergeCharFormat(colorFormat);

         }

     }

打印文本,QTextEdit可以自动在一页大小的地方断开,以适应打印。QTextDocument提供print()函数允许打印。例如所示代码:

     QTextDocument *document = editor->document();

     QPrinter printer;

     QPrintDialog *dlg = new QPrintDialog(&printer, this);

     if (dlg->exec() != QDialog::Accepted)

         return;

     document->print(&printer);

 

Advanced Rich Text Processing

处理大文件

Qt 不限制文本处理的文件大小,对于大多数情况而言,这将不会出现问题。文件大小依赖于你硬件和你的Qt程序实现。

如果你面对了这个问题,我们推荐你

1. 你应该考虑断开大段成为更小的段落,你也可以定期插入换行符,这样就看起来像QTextEdit的一个大段。

2. 你可以在QTextDocument中用maximumBlockCount()减少块的数量,文档只和QTextEdit涉及到的块数量大小相当。

3. 当增加文本到一个文本编辑时,这是一个增加文本到编辑块(看下例)的优势。结果是文本编辑不是立刻需要全部文档结构的。

下面的例子我们假设文本编辑是可见的。

   textEdit.show();

   textCursor.beginEditBlock();

  

   for (int i = 0; i < 1000; ++i) {

       textCursor.insertBlock();

       textCursor.insertText(paragraphText.at(i));

   }

   textCursor.endEditBlock();

 

Supported HTML Subset

Widgets使用QTextDocument能够展示特殊的富文本,例如QLabel, QTextEdit

Text Widget使用HTML标记

Widget会在展示时自动删除HTML标记,并根据含义展示富文本。例如,设置一个文本标签:"<b>Hello</b> <i>Qt!</i>",它会展示出这样:Hello Qt

所支持的标记有:

Tag

Description

Comment

a

Anchor or link

Supports the href and name attributes. Note that the :visited selector is one of those that is not supported by the rich text engine. See below for a list of others.

address

Address

b

Bold

big

Larger font

blockquote

Indented paragraph

body

Document body

Supports the bgcolor attribute, which can be a Qt color name or a #RRGGBB color specification.

br

Line break

center

Centered paragraph

cite

Inline citation

Same as i.

code

Code

Same as tt.

dd

Definition data

dfn

Definition

Same as i.

div

Document division

Supports the standard block attributes.

dl

Definition list

Supports the standard block attributes.

dt

Definition term

Supports the standard block attributes.

em

Emphasized

Same as i.

font

Font size, family, and/or color

Supports the following attributes: size, face, and color (Qt color names or #RRGGBB).

h1

Level 1 heading

Supports the standard block attributes.

h2

Level 2 heading

Supports the standard block attributes.

h3

Level 3 heading

Supports the standard block attributes.

h4

Level 4 heading

Supports the standard block attributes.

h5

Level 5 heading

Supports the standard block attributes.

h6

Level 6 heading

Supports the standard block attributes.

head

Document header

hr

Horizontal line

Supports the width attribute, which can be specified as an absolute or relative (%) value.

html

HTML document

i

Italic

img

Image

Supports the src, source (for Qt 3 compatibility), width, and height attributes.

kbd

User-entered text

meta

Meta-information

If a text encoding is specified using the meta tag, it is picked up by Qt::codecForHtml(). Likewise, if an encoding is specified toQTextDocument::toHtml(), the encoding is stored using a meta tag, for example:

 <meta http-equiv="Content-Type" content="text/html; charset=EUC-JP" />

li

List item

nobr

Non-breakable text

ol

Ordered list

Supports the standard list attributes.

p

Paragraph

Left-aligned by default. Supports the standard block attributes.

pre

Preformated text

qt

Qt rich-text document

Synonym for html. Provided for compatibility with earlier versions of Qt.

s

Strikethrough

samp

Sample code

Same as tt.

small

Small font

span

Grouped elements

strong

Strong

Same as b.

style

Style sheet

Allows styling information to be included with the rich text. A limited subset of CSS syntax can be used to change the appearance of the text.

sub

Subscript

sup

Superscript

table

Table

Supports the following attributes: border, bgcolor (Qt color names or #RRGGBB), cellspacing, cellpadding, width(absolute or relative), and height.

tbody

Table body

Does nothing.

td

Table data cell

Supports the standard table cell attributes.

tfoot

Table footer

Does nothing.

th

Table header cell

Supports the standard table cell attributes.

thead

Table header

If the thead tag is specified, it is used when printing tables that span multiple pages.

title

Document title

The value specified using the title tag is available through QTextDocument::metaInformation().

tr

Table row

Supports the bgcolor attribute, which can be a Qt color name or a #RRGGBB color specification.

tt

Typewrite font

u

Underlined

ul

Unordered list

Supports the standard list attributes.

var

Variable

Same as i.

block属性。这下面的属性被div, dl, dt, h1, h2, h3, h4, h5, h6, p支持:

  align(left, right, center, justify)

  dir(ltr, rtl)

列表list属性。下面的属性被ol, ul支持:

  type (1, a, A, square, disc, circle)

表单位Table Cell属性。下面的被td, th标记支持:

  width (absolute, relative, or no-value)

  bgcolor (Qt color names or #RRGGBB )

  colspan

  rowspan

  align (left, right, center, justify)

  valign (top, middle, bottom)

CSS属性

Version:Property

Values

Description

background-color

<color>

Background color for elements

background-image

<uri>

Background image for elements

color

<color>

Text foreground color

font-family

<family name>

Font family name

font-size

[ small | medium | large | x-large | xx-large ] | <size>pt | <size>px

Font size relative to the document font, or specified in points or pixels

font-style

[ normal | italic | oblique ]

font-weight

[ normal | bold | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 ]

Specifies the font weight used for text, where normal and bold are mapped to the corresponding QFont weights. Numeric values are 8 times the equivalent QFont weight values.

text-decoration

none | [ underline || overline || line-through ]

Additional text effects

font

[ [ <'font-style'> || <'font-weight'> ]? <'font-size'> <'font-family'> ]

Font shorthand property

text-indent

<length>px

First line text indentation in pixels

white-space

normal | pre | nowrap | pre-wrap

Declares how whitespace in HTML is handled.

margin-top

<length>px

Top paragraph margin in pixels

margin-bottom

<length>px

Bottom paragraph margin in pixels

margin-left

<length>px

Left paragraph margin in pixels

margin-right

<length>px

Right paragraph margin in pixels

padding-top

<length>px

Top table cell padding in pixels

padding-bottom

<length>px

Bottom table cell padding in pixels

padding-left

<length>px

Left table cell padding in pixels

padding-right

<length>px

Right table cell padding in pixels

padding

<length>px

Shorthand for setting all the padding properties at once.

vertical-align

baseline | sub | super | middle | top | bottom

Vertical text alignment. For vertical alignment in text table cells only middle, top, and bottom apply.

border-color

<color>

Border color for text tables.

border-style

none | dotted | dashed | dot-dash | dot-dot-dash | solid | double | groove | ridge | inset | outset

Border style for text tables.

background

[ <'background-color'> || <'background-image'> ]

Background shorthand property

page-break-before

[ auto | always ]

Make it possible to enforce a page break before the paragraph/table

page-break-after

[ auto | always ]

Make it possible to enforce a page break after the paragraph/table

float

[ left | right | none ]

Specifies where an image or a text will be placed in another element. Note that the floatproperty is only supported for tables and images.

text-transform

[ uppercase | lowercase ]

Select the transformation that will be performed on the text prior to displaying it.

font-variant

small-caps

Perform the smallcaps transformation on the text prior to displaying it.

word-spacing

<width>px

Specifies an alternate spacing between each word.

支持CSS选择器,所有CSS2.1选择器都支持,除了pseudo-class选择器,例如:first-child, :visited 和 :hover

 

 

 

 

你可能感兴趣的:(C++,C++,qt,qt,qt)