前言
富文本文档的文档元素:QTextFrame类和QTextFrameFormat,类的层次结构如下图所示:
QTextFrame 类
QTextFrame 类表示QTextDocument 中的框架,为文档中的文本提供结构,用作其他的文档元素的泛型容器。框架通常使用QTextCursor::insertFrame()创建。
框架可用于在富文本文档中创建分层结构。每个文档都有一个根框架(QTextDocument::rootFrame() ),根框架下方的每个框架都有一个父框架和(可能为空的)子框架列表。可以使用parentFrame()找到父帧, childFrames() 功能提供子框架的列表。
每个框架至少包含一个文本块,以使文本光标在其中插入新的文档元素。因此,QTextFrame::iterator类用于遍历给定框架中的块和子帧。框架中的第一个和最后一个子元素可以用 begin() 和 end() 找到。
框架还具有格式(使用QTextFrameformat 指定),可以使用setFormat() 进行设置,使用格式 format() 读取。
可以获得文本光标,该光标指向框架中的第一个和最后一个有效光标位置;分别使用firstCursorPosition( ) 和lastCursorPosition( ) 函数。
可以使用firstPosition( )和lastPosition( )找到文档中框架的范围。
您可以使用 QTextFrame :: iterator 类遍历框架的内容:这提供对其内部文本块和子框架列表的只读访问。
QTextFrameFormat类
QTextFrameFormat类为QTextDocument中的框架提供格式信息。
一个文本框架将一个或多个文本块组合在一起,从而提供了一个比段落大的结构层。 框架的格式指定如何在屏幕上呈现和定位框架。 它不直接指定内部文本格式的行为,但提供了对其子级布局的约束。
框架格式定义屏幕上框架的width()和height()。 每个框架都可以有一个border(),用矩形框将其内容包围。 边框由框架周围的margin()包围,并且框架的内容通过框架的padding()与边框保持分开。 此方案类似于级联样式表用于HTML页面的框模型。
框架的position()是使用setPosition()设置的,并确定它相对于周围文本的位置。
QTextFrameFormat对象的有效性可以通过isValid()函数来确定。
代码示例
主要代码如下:
#include "Widget.h"
#include <QtWidgets>
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
edit = new QTextEdit;
QVBoxLayout *mainLayout = new QVBoxLayout(this);
mainLayout->addWidget(edit);
resize(600,400);
QTextDocument *doc = edit->document();
setRootFrameFormat(doc);
edit->append("hello RTF");
insertRightFrame(doc,"你是谁?");
insertLeftFrame(doc,"我也想知道呢!");
insertRightFrame(doc,"那你从哪儿来?");
insertLeftFrame(doc,"莫名其妙就来了.");
navigateDoc(doc);
}
void Widget::setRootFrameFormat(QTextDocument *doc)
{
QTextFrame *root_frame = doc->rootFrame();
QTextFrameFormat root_frame_format = root_frame->frameFormat();//创建框架格式
root_frame_format.setBorderBrush(Qt::red);//设置边界颜色
root_frame_format.setBorder(1);//设置边界宽度
root_frame_format.setBackground(QColor("aliceblue"));//设置边界宽度
root_frame->setFrameFormat(root_frame_format); //给框架使用格式
}
void Widget::insertRightFrame(QTextDocument *doc,const QString &text)
{
QTextFrameFormat format;
format.setBackground(Qt::green);//设置背景色
format.setMargin(1);//设置边距
format.setPadding(5);//设置填充
format.setBorder(1);//设置边界宽度
format.setWidth(QTextLength(QTextLength::PercentageLength, 55));//宽度设置
format.setPosition(QTextFrameFormat::FloatRight);
QTextCursor cursor = doc->rootFrame()->lastCursorPosition();
cursor.insertFrame(format);
cursor.insertText(text);
}
void Widget::insertLeftFrame(QTextDocument *doc, const QString &text)
{
QTextFrameFormat format;
format.setBackground(Qt::yellow);//设置背景色
format.setMargin(1);//设置边距
format.setPadding(5);//设置填充
format.setBorder(1);//设置边界宽度
format.setWidth(QTextLength(QTextLength::PercentageLength, 55));//宽度设置
format.setPosition(QTextFrameFormat::FloatLeft);
QTextCursor cursor = doc->rootFrame()->lastCursorPosition();
cursor.insertFrame(format);
cursor.insertText(text);
}
//浏览文档
void Widget::navigateDoc(QTextDocument *doc)
{
QTextFrame *frame = doc->rootFrame();
navigateFrame(frame);
qDebug() << "---------";
navigateBlocks(doc);
}
//浏览文本框架
void Widget::navigateFrame(QTextFrame *frame)
{
QTextFrame::iterator it;
for (it = frame->begin(); !it.atEnd(); it++) {
QTextBlock b = it.currentBlock();
QTextFrame * childFrame = it.currentFrame();
if(b.isValid() && !b.text().isEmpty())
qDebug() << b.text();
if(childFrame){
// 递归调用,和浏览文件目录的方式类似。
navigateFrame(childFrame);
}
}
}
// 还是用文本块的迭代器比较方便,文本块之间有着前后联系
void Widget::navigateBlocks(QTextDocument *doc)
{
QTextBlock b = doc->begin();
while(b.isValid()){
if(!b.text().isEmpty())
qDebug() << b.text();
b = b.next();
}
}
总结
QTextFrame提供了文档元素的容器存放功能,QTextformat 提供了QTextFrame显示样式,主要内容都很少,主要是理解和运用,插入框架时,要设置合适的游标位置,才能准确的插入。