Qt 富文本处理(08):框架和框架格式

前言

  富文本文档的文档元素: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显示样式,主要内容都很少,主要是理解和运用,插入框架时,要设置合适的游标位置,才能准确的插入。

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值