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

news2025/1/17 16:04:59

文章目录

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


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


Qt富文本处理

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

富文本文档结构

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

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

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

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

在这里插入图片描述

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

在这里插入图片描述

框架属性示意图:

在这里插入图片描述

  • 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就会高亮显示。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/161983.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

给定一个有序数组arr,代表坐落在X轴上的点 给定一个正数K,代表绳子的长度 返回绳子最多压中几个点? 即使绳子边缘处盖住点也算盖住

目录暴力求解贪心二分法滑动窗口对数器测试题目&#xff1a; 给定一个有序数组arr&#xff0c;代表坐落在X轴上的点 给定一个正数K&#xff0c;代表绳子的长度 返回绳子最多压中几个点&#xff1f; 即使绳子边缘处盖住点也算盖住 这道题有三个解决方案 暴力求解 //暴力求解O(N…

Docker容器MySQL数据库的备份与还原,以及每天定时自动备份.

1.快速启动mysql容器 1&#xff1a;拉取mysql镜像&#xff1a; 根据自己需要&#xff0c;我这个是5.7版本的镜像。 docker pull nanlist/mysql:5.72&#xff1a;宿主机建立挂载目录&#xff1a; mkdir三个文件夹&#xff0c;方便持久化。 /home/mysql/conf /home/mysql/log…

java面试资料(二)

这里写目录标题Spring什么是 Spring Framework&#xff1f;列举 Spring Framework 的优点。Spring Framework 有哪些不同的功能&#xff1f;Spring Framework 中有多少个模块&#xff0c;它们分别是什么&#xff1f;什么是 Spring 配置文件&#xff1f;Spring 应用程序有哪些不…

MySQL数据同步ES的4种方法,你能想到几种?

大家好&#xff0c;我是老三&#xff0c;这期给大家分享一个电商中常见的场景——MySQL数据同步Elasticsearch。 大家应该都在各种电商网站检索过商品&#xff0c;那么检索商品一般都是通过什么实现呢&#xff1f;搜索引擎Elasticsearch。 那么问题来了&#xff0c;商品上架&a…

【布隆过滤器】如何防止缓存穿透、海量邮箱的垃圾邮件过滤等问题?

目录 一、布隆过滤器是什么&#xff1f; 二、布隆过滤器的模拟实现 2.1、模拟实现 2.2、布隆过滤器的优点和缺点 优点&#xff1a; 缺点&#xff1a; 2.3、布隆过滤器的删除功能 2.4、布隆过滤器的使用场景 一、布隆过滤器是什么&#xff1f; 它是一种概率型数据结构&am…

敏捷.概念辨析

第一部分 1. 最小可行产品MVP&#xff08;Minimum Viable Product&#xff09; 在很多同学的脑海里&#xff0c;MVP就是你想传达给用户的功能的最小集合。 错&#xff0c;完全错。 问题不在于“你觉得应该……”&#xff0c;关键是“用户目前感觉……”。我们预设了立场&am…

Android Glide 4.9 常见方法总结

转载请标明出处&#xff1a;http://blog.csdn.net/zhaoyanjun6/article/details/128665358 本文出自【赵彦军的博客】 文章目录依赖submit 下载图片DrawableImageViewTargetRequestListener 加载圆角图片回调圆形 CircleCrop圆角 RoundedCornersFitCenterCenterCropCenterInsid…

RK3399平台开发系列讲解(中断篇)ARM64异常处理详解

🚀返回专栏总目录 文章目录 一、异常级别二、异常分类三、异常向量表四、异常处理沉淀、分享、成长,让自己和他人都能有所收获!😄 一、异常级别 📢ARM64的处理器支持多个异常等级(exception level),其中EL0是用户模式,EL1是内核模式,也称为特权模式;EL2 是虚拟化…

算力狂热时代的冷静之道:宁畅总裁秦晓宁分享企业的算力最优解

算力是数字化时代的生产力之源&#xff0c;近年来已经成为共识。所以&#xff0c;我们能看到各个层面对算力的追逐&#xff0c;无论是国家层面的政策利好&#xff0c;算力基础设施建设的加速&#xff0c;还是诸多行业和企业积极地增加算力部署&#xff0c;呈现出一片如火如荼的…

958. 二叉树的完全性检验

958. 二叉树的完全性检验 难度中等 给定一个二叉树的 root &#xff0c;确定它是否是一个 完全二叉树 。 在一个 完全二叉树 中&#xff0c;除了最后一个关卡外&#xff0c;所有关卡都是完全被填满的&#xff0c;并且最后一个关卡中的所有节点都是尽可能靠左的。它可以包含 …

AWVS扫描Web应用程序

AWVS扫描Web应用程序 系列文章 AWVS安装与激活 1.账户密码登录扫描 我们准备了一个靶场用来做测试扫描&#xff1a; 1.点击【Targets】&#xff0c;点击【add Target】 2.输入扫描地址和扫描描述,点击【save】 3.点击【Site Login】 4.选择【try to auto-login into the si…

降本增效,软件质量是要降还是要升?

最近一年&#xff0c;裁员潮席卷而来&#xff0c;意味着许多企业经营遇到了很大困难&#xff0c;“降本增效”自然成了企业的主旋律&#xff1a;内部研发和运营要努力降低成本&#xff0c;外部市场想突出重围、开拓新局面&#xff0c;创造新营收&#xff0c;企业才能渡过难关&a…

DeViSE: A Deep Visual-Semantic Embedding Model

摘要 现代视觉识别系统受限于其能力为&#xff1a;扩大大规模数量的目标类别。 scale to large numbers of object categoriestext data :文本数据这篇文章我们提出一个a new deep visual-semantic embedding model从unannotated text 中收集的语义信息和有标签的图像数据。o…

经纬恒润荣膺2022年度中国港口协会科学技术奖一等奖!

近日&#xff0c;2022年度中国港口协会科学技术奖评终审答辩会在青岛圆满闭幕&#xff0c;经纬恒润和山东港口日照港集装箱发展有限公司共同申报的“顺岸开放式全自动化集装箱码头集卡无人驾驶关键技术研究和应用”获得2022年度中国港口协会科技进步奖一等奖。 中国港口协会科学…

[go]深入学习Go总结

Go 深入学习 文章目录Go 深入学习编译过程概念编译四阶段词法分析 语法分析类型检查中间代码生成机器码生成类型系统分类底层类型类型相同类型赋值类型强制转换类型方法自定义类型方法方法调用方法调用时的类型转换类型断言接口类型查询数据结构数组初始化访问和赋值切片数据结…

【Java】Java的面向对象笔记(上)(二)

再谈方法 Overload 重载 定义&#xff1a;在同一个类中&#xff0c;允许存在一个以上的同名方法&#xff0c;只要它们的参数个数或者参数类型不同即可。 两同一不同 同一个类、相同方法名参数列表不同&#xff1a;参数个数不同&#xff0c;参数类型不同&#xff0c;参数顺序不…

SpringBoot 数据源的自动配置HikariDataSource以及使用Druid数据源

目录 &#xff08;一&#xff09;、数据源的自动配置-HikariDataSource 1、导入JDBC场景 2、分析自动配置 3、修改配置项 4、测试 &#xff08;二&#xff09;、使用Druid数据源 1、druid官方github地址 2、自定义方式 3、使用官方starter方式 &#xff08;一&#xf…

汇编语言【王爽】实验一、二

实验一&#xff1a;查看CPU和内存&#xff0c;用机器指令和汇编指令编程 debug环境搭建&#xff1a;参考此文 assignment 1 用A命令向内存中写入汇编指令&#xff0c;用U命令查看 用R命令分别修改CS、IP寄存器&#xff0c;即CS:IP的指向&#xff0c;用T命令逐条执行 assignm…

小兔子在终端给大家拜年啦

小兔子在终端给大家拜年啦前言创作过程小兔子模型制作实现思路代码小结耐心和持久胜过激烈和狂热。 哈喽大家好&#xff0c;我是陈明勇&#xff0c;本文分享的内容是 使用 Go 语言实现小兔子在终端给大家拜年。如果觉得作品有趣&#xff0c;不妨点个赞&#xff0c;如果本文有错…

【学习笔记】决策树 (1.简介+基本构建思想)

简单问题引入 如何判断今天是什么季节&#xff1f;春天、夏天、秋天、冬天&#xff1f; 如果是我们的话&#xff0c;可以通过日期一下子知道今天的季节——“7月份&#xff0c;所以是夏天&#xff01;”大概是这样的发言。 但如果不让你通过日期来判断呢&#xff1f;选择还是…