【Qt】富文本处理简单介绍

文章目录

  • Qt富文本处理
    • 富文本文档结构
    • 文本块QTextBlock
    • 表格、列表、图片
    • 查找功能
    • 语法高亮与HTML


参考《Qt Creator快速入门(第三版)》。


Qt富文本处理

富文本Rich Text,简单说就是在文档中可以使用多种格式,比如字体颜色、图片和表格等,是与纯文本相对而言的。比如Windows上的记事本就是纯文本编辑器,word是富文本编辑器。

富文本文档结构

Qt对富文本的处理分为编辑操作和只读操作两种方式。

  • 编辑操作使用基于光标的一些接口函数,更好地模拟用户的编辑操作,更加容易理解,而且不会丢失底层的文档框架;
  • 对于文档结构的概览,使用了只读的分层次的接口函数,有利于文档的检索和输出。

所以对于文档的读取和编辑要使用不同的两组接口。文档的光标主要基于QTextCursor类,文档的框架主要基于QTextDocument类。

一个富文本文档的结构分为几种元素来表示,分别是:框架、文本块、表格、列表,每种元素的格式又使用相应的format类来表示。

【Qt】富文本处理简单介绍_第1张图片

一个空的文档包含了一个根框架,这个根框架又包含一个空的文本块,在根框架中又可以再添加文本块、子框架、表格等。

【Qt】富文本处理简单介绍_第2张图片

框架属性示意图:

【Qt】富文本处理简单介绍_第3张图片

  • Margin是边界外与其它内容间的空白;
  • padding是边界内与本身内容间的空白;
  • border是边界;
  • content是内容;

获取编辑器的文档对象,获取文档的根框架并重新设置框架的格式,示例代码:

    // 获取文档对象
    QTextDocument *textDocument = ui->textEdit->document();
    // 获取根框架
    QTextFrame *rootFrame = textDocument->rootFrame();
    // 创建框架格式
    QTextFrameFormat textFrameFormat;
    // 设置框架的边界颜色
    textFrameFormat.setBorderBrush(Qt::red);
    // 设置框架的边界宽度
    textFrameFormat.setBorder(2);
    // 设置根框架使用框架格式
    rootFrame->setFrameFormat(textFrameFormat);

在根框架中再添加一个子框架,示例代码:

    // 在根框架中再添加一个子框架
    QTextFrameFormat frameFormat;  // 框架格式
    // 设置背景颜色
    frameFormat.setBackground(Qt::lightGray);
    // 设置边距
    frameFormat.setMargin(10);
    // 设置填衬
    frameFormat.setPadding(5);
    // 设置边界宽度
    frameFormat.setBorder(3);
    // 设置边框样式
    frameFormat.setBorderStyle(QTextFrameFormat::BorderStyle_Dotted);
    // 获取光标
    QTextCursor cursor = ui->textEdit->textCursor();
    // 在光标处插入框架
    cursor.insertFrame(frameFormat);

文本块QTextBlock

文本块类QTextBlock为文本文档提供一个文本片段的容器。一个回车换行表示创建一个新的文本块,一个文本块可以看作一个段落。

QTextBlock提供了只读接口。

文本块的格式由QTextBlockFormat类来处理,主要涉及对齐方式、文本块四周边距、缩进等内容。

文本块中的文本内容的格式由QTextCharFormat类处理,比如字体大小、加粗、下划线等。

实现遍历文档中的框架示例代码:

void MainWindow::showTextFrame()  // 遍历框架
{
    // 获取文档
    QTextDocument *document = ui->textEdit->document();
    // 获取根框架
    QTextFrame *frame = document->rootFrame();
    // 建立QTextFrame类的迭代器
    QTextFrame::iterator it;
    for(it = frame->begin();it != frame->end();++it)
    {
        // 获取当前框架的指针, currentFrame()如果获取到的是文本块则返回0
        QTextFrame *childFrame = it.currentFrame();  
        // 获取当前文本块,currentBlock()如果获取到的是框架,则返回的块无效,可以用isValid()判断返回的块是否OK
        QTextBlock childBlock = it.currentBlock();

        if(childFrame)
            qDebug() << tr("frame");

        if(childBlock.isValid())
            qDebug() << tr("block:") << childBlock.text();
    }
}

遍历所有文本块示例代码:

void MainWindow::showTextBlock()
{
    // 遍历文本块
    // 获取文档
    QTextDocument * document = ui->textEdit->document();
    QTextBlock block = document->firstBlock();  // 获取文档的第一个文本块
    for(int i=0;i<document->blockCount();++i)  // blockCount()获取文档中所有文本块的个数
    {
        qDebug() << tr("文本块 %1,文本块首行行号为:%2,长度为:%3,内容为:%4")
                    .arg(i)
                    .arg(block.firstLineNumber())
                    .arg(block.length())
                    .arg(block.text());
         block = block.next();  // 获取下一个文本块
    }
}

编辑操作,设置文本块格式,文本块中的文本内容格式、并插入文本进行测试,示例代码:

void MainWindow::setTextFont(bool checked)
{
    // 设置字体格式
    if(checked)  // 如果处于选中状态
    {
        // 获取文本块的光标
        QTextCursor cursor = ui->textEdit->textCursor();
        // 设置文本块格式
        QTextBlockFormat blockFrame;
        blockFrame.setAlignment(Qt::AlignCenter);  // 设置水平剧中
        cursor.insertBlock(blockFrame);  // 使用文本块格式
        QTextCharFormat charFormat;  // 设置字符格式
        charFormat.setBackground(Qt::darkGray);  // 设置背景色
        charFormat.setForeground(Qt::blue);  // 设置字体颜色
        charFormat.setFont(QFont(tr("宋体"),12,QFont::Bold,true));  // 设置字体为宋体,字号12,粗体 斜体
        charFormat.setFontUnderline(true);  // 设置使用下划线
        cursor.setCharFormat(charFormat); // 设置使用字符格式
        cursor.insertText(tr("测试字体"));  // 插入文本
    }
    else
    {
        qDebug() << tr("未选择字体,执行其它操作");
    }
}

表格、列表、图片

表格和列表也可以使用QTextFrame::iterator来遍历它们。

表格对应的是QTextTable类,该类提供了一些常用函数:

  • QTextTable::cellAt()来获取指定的单元格;
  • QTextTable::insertColumns()用来插入列;
  • QTextTable::insertRows()用来插入行;
  • QTextTable::mergeCells()用来合并单元格;
  • QTextTable::splitCell()用来拆分单元格;

表格中的单元格对应的类是QTextTableCell,对应的格式类是QTextTableCellFormat类。

列表对应的类是QTextList,该类提供了一些常用函数:

  • QTextList::count()用来获取列表中项目的个数;
  • QTextList::item()用来获取指定项目的文本块;
  • QTextList::removeItem()删除一个项目;

图片使用QTextImageFormat类,可以使用QTextImageFormat::setHeight()和QTextImageFormat::setWidth()设置图片的高度和宽度,可以使用QTextImageFormat::setName()指定图片。

示例代码:

void MainWindow::insertTable()
{
    // 插入表格
    QTextCursor cursor = ui->textEdit->textCursor();
    QTextTableFormat format;
    format.setCellSpacing(2);  // 设置表格的单元格间距,相邻单元格之间的距离
    format.setCellPadding(10);  // 设置单元格边框与内容之间的距离
    cursor.insertTable(2,2,format);  // 在当前光标处插入2行2列的表格
}

void MainWindow::insertList()  // 插入列表
{
    QTextListFormat format;
    format.setStyle(QTextListFormat::ListLowerAlpha);  // 设置列表格式为数字编号
    ui->textEdit->textCursor().insertList(format);
}

void MainWindow::insertImage()  // 插入图片
{
    QTextImageFormat format;
    format.setName(":/images/BackButton.png");  //  设置图片路径
    ui->textEdit->textCursor().insertImage(format);
}

查找功能

类似字体设置等的操作可以在QTextEdit等富文本编辑类中直接进行,QTextEdit提供了很多方便的函数,比如常用的复制、粘贴、撤销、恢复、放大、缩小等操作。

这里介绍文本查找功能,使用的是QTextEdit::find()函数。

更多的查找功能可以使用QTextDocument类的find函数,还可以使用正则表达式。

QTextEdit::find()查找字符示例代码:

void MainWindow::findNext()  // 查找下一个
{
    QString str = lineEdit->text();  // 获取要查找的字符串
    // 使用查找函数查找指定字符串,查找方式为向后查找
    bool isFind = ui->textEdit->find(str,QTextDocument::FindBackward);
    if(isFind)  // 如果找到
    {
        qDebug() << tr("行号:%1 列号:%2")
                    .arg(ui->textEdit->textCursor().blockNumber())
                    .arg(ui->textEdit->textCursor().columnNumber());
    }
    else{
        qDebug() << tr("没有找到,从头开始查找");
        ui->textEdit->textCursor().setPosition(1,QTextCursor::MoveAnchor);
    }
}

语法高亮与HTML

Qt的富文本处理中类QSyntaxHighlighter实现语法高亮。要实现这个功能,需要创建QSyntaxHighlighter类的子类,然后重新实现highlightBlock()函数,使用时直接将QTextDocument类对象指针作为其父部件指针,这样的话就可以自动调用highlightBlock()函数了。

首先新建QSyntaxHighlighter的子类,设置构造函数传入的父类为QTextDocument指针对象,并在子类中重写highlightBlock()函数。

void MySyntaxHighlighter::highlightBlock(const QString &text)
{
    // 重新实现文本块高亮函数
    QTextCharFormat myFormat;
    myFormat.setFontWeight(QFont::Bold);  // 将文本的字体设置为粗体
    myFormat.setForeground(Qt::green);  // 将文本内容颜色设置为绿色
    QString pattern = "\\bchar\\b";  // 要匹配的字符,这里匹配 char 单词
    QRegExp expression(pattern);
    int index = text.indexOf(expression);  // 从位置0开始匹配字符串,匹配成功返回字符串的起始位置
    while (index >= 0) {
        int length = expression.matchedLength();  // 要匹配的字符串的长度
        setFormat(index,length,myFormat);  // 对要匹配的字符串设置格式
        index = text.indexOf(expression,index+length);  // 继续匹配
    }
}

在调用函数中,创建MySyntaxHighlighter类对象,并传入QTextEdit的文档对象。此时在编辑器中输入char就会高亮显示。

你可能感兴趣的:(QT,qt,ui,开发语言)