版权声明:若无来源注明,Techie亮博客文章均为原创。 转载请以链接形式标明本文标题和地址:
本文标题:Qt富文本编辑器QTextDocument     本文地址:https://www.techieliang.com/2017/12/726/

1. 介绍

对于文本编辑,qt提供了很多控件

  • QLineEdit:单行文本输入,比如用户名密码等简单的较短的或者具有单一特征的字符串内容输入。使用text、settext读写
  • QTextEdit:富文本编辑器,支持html显示,可以用sethtml/tohtml进行html文本操作或使用,也可利用setPlainText、toPlainText进行纯文本操作
  • QPlainTextEdit:纯文本编辑器,使用了近似于textedit的技术并做了纯文本编辑的优化,并具有文章段落的概念也提供了撤销等功能,但不支持html显示。
  • QTextBrowser:继承于QTextEdit,仅提供显示功能,并提供了超文本导航功能,如果不需要超文本连接只需要使用QTextEdit并设置QTextEdit::setReadOnly

上述都是显示控件,可以确定的是富文本编辑器要用QTextEdit或者QPlainTextEdit,但是肯定不能主动撰写html代码或者逐个处理显示格式实现富文本,实际上Qt提供了相关类:QTextDocument富文本文档、QTextBlock文本快、QTextFrame框架、QTextTable表格、QTextList列表、QTextCursor指针位置、QTextXXXXFormat各种数据类型样式。对于富文本的所有帮助请见官方文档:Rich Text Processing

QTextEdit和QPlainTextEdit选择:差异是QTextEdit提供了tohtml,如果想在处理完文档,直接根据文档生成html作为博客等内容,可以使用此类,没有需要后者即可

注意关系:QTextDocument>QTextFrame>QTextBlock/QTextTable/QTextList前包含后

查看两个类的api,均提供了document方法,可以返回QTextDocument指针,用于通过QTextDocument的方式操作文档内容格式,官方范例:

Application Example这个比较简单

Syntax Highlighter Example语法高亮的例子

Text Edit Example类似于word编辑器的例子

Calendar Example利用富文本编辑器的方式实现日历(不建议学这个毕竟已经有现成的日历控件,而且文档中往往也不会插入日历)

Order Form Example根据一些的参数设置生成报表,其实和上面的原理一样

2. 基本使用

首先当具有一个edit时,不需要自行创建document,可以直接用document方法可以获取当前edit的document

QTextDocument只是一个文档,其内还有根节点,需要使用QTextDocument::rootFlrame获取,设置根节点的边框粗细、颜色就类似于设置word文档边框底纹

2.1. 简单范例

  1. #include "mainwindow.h"
  2. #include "ui_mainwindow.h"
  3. #include <QTextDocument>
  4. #include <QTextFrame>
  5. #include <QTextBlock>
  6. MainWindow::MainWindow(QWidget *parent) :
  7. QMainWindow(parent),
  8. ui(new Ui::MainWindow) {
  9. ui->setupUi(this);
  10. QTextDocument* doc = ui->textEdit->document();
  11. QTextFrame *root_frame = doc->rootFrame();
  12. QTextFrameFormat root_frame_format = root_frame->frameFormat();//创建框架格式
  13. root_frame_format.setBorderBrush(Qt::darkBlue);//设置边界颜色
  14. root_frame_format.setBorder(5);//设置边界宽度
  15. root_frame->setFrameFormat(root_frame_format); //给框架使用格式
  16. QTextFrameFormat frame_format;
  17. frame_format.setBackground(Qt::darkRed);//设置背景色
  18. frame_format.setMargin(10);//设置边距
  19. frame_format.setPadding(5);//设置填充
  20. frame_format.setBorder(2);//设置边界宽度
  21. frame_format.setBorderStyle(
  22. QTextFrameFormat::BorderStyle_Solid);//设置边框样式
  23. frame_format.setPosition(QTextFrameFormat::FloatRight);//右侧
  24. frame_format.setWidth(QTextLength(
  25. QTextLength::PercentageLength, 40));//宽度设置
  26. QTextCursor cursor = ui->textEdit->textCursor();
  27. cursor.insertText("A company");
  28. cursor.insertBlock();
  29. cursor.insertText("321 City Street");
  30. cursor.insertBlock();
  31. cursor.insertFrame(frame_format);
  32. cursor.insertText("Industry Park");
  33. cursor.insertBlock();
  34. cursor.insertText("Another country");
  35. }

上述代码仅显示了四行文字,前两行在root跟框架显示,后两行在一个新建的frame中显示,并将frame置于右侧限定了宽度,更多的布局方法请参考:Order Form Example

上述并未对文本格式做设置,可以在insertText的第二个参数直接赋予一个文本格式QTextCharFormat

2.2. QTextCursor光标操作/遍历嵌套Frame/遍历所有Block

首先他有各种instert函数可以插入上面提到的各种文档中的数据类型。有时并不能一次准确的建立好整个文档,需要在中间插入,这样就需要setPosition命令,而positon的具体值可以通过上述各种数据类型的类获取到每个块或者框架或者其他类型开头的positon,也可以通过length获取到当前块的长度用于定位末尾位置。下面提供一个简单范例

  1. #include "mainwindow.h"
  2. #include "ui_mainwindow.h"
  3. #include <QTextDocument>
  4. #include <QTextFrame>
  5. #include <QTextBlock>
  6. #include <QDebug>
  7. MainWindow::MainWindow(QWidget *parent) :
  8. QMainWindow(parent),
  9. ui(new Ui::MainWindow) {
  10. ui->setupUi(this);
  11. QTextDocument* doc = ui->textEdit->document();
  12. QTextFrame *root_frame = doc->rootFrame();
  13. QTextFrameFormat root_frame_format = root_frame->frameFormat();//创建框架格式
  14. root_frame_format.setBorderBrush(Qt::darkBlue);//设置边界颜色
  15. root_frame_format.setBorder(5);//设置边界宽度
  16. root_frame->setFrameFormat(root_frame_format); //给框架使用格式
  17. QTextFrameFormat frame_format;
  18. frame_format.setBackground(Qt::darkRed);//设置背景色
  19. frame_format.setMargin(10);//设置边距
  20. frame_format.setPadding(5);//设置填充
  21. frame_format.setBorder(2);//设置边界宽度
  22. frame_format.setBorderStyle(
  23. QTextFrameFormat::BorderStyle_Solid);//设置边框样式
  24. frame_format.setPosition(QTextFrameFormat::FloatRight);//右侧
  25. frame_format.setWidth(QTextLength(
  26. QTextLength::PercentageLength, 40));//宽度设置
  27. QTextCursor cursor = ui->textEdit->textCursor();
  28. cursor.insertText("A company");
  29. cursor.insertBlock();
  30. cursor.insertText("321 City Street");
  31. cursor.insertFrame(frame_format);
  32. cursor.insertText("Industry Park");
  33. cursor.insertBlock();
  34. cursor.insertText("Another country");
  35. //遍历frame
  36. for(auto block = root_frame->begin();!block.atEnd();++block) {
  37. if(block.currentBlock().isValid()) {
  38. qDebug()<<block.currentBlock().text();
  39. }
  40. else if(block.currentFrame()) {//frame嵌套,范例只有两层所以不递归了
  41. auto child_frame = block.currentFrame();
  42. for(auto block2 = child_frame->begin();!block2.atEnd();++block2) {
  43. if(block.currentBlock().isValid()) {
  44. qDebug()<<block2.currentBlock().text();
  45. }
  46. }
  47. }
  48. }
  49. //还可以通过root_frame->childFrames()直接获取所字frame
  50. //遍历文本块
  51. QTextBlock block = doc->firstBlock();
  52. for(int i = 0; i < doc->blockCount();i++) {
  53. qDebug() << QString("block num:%1\tblock first line number:%2\tblock length:%3\ttext:")
  54. .arg(i).arg(block.firstLineNumber()).arg(block.length())
  55. << block.text();
  56. block = block.next();
  57. }
  58. QTextBlock insert_block = doc->firstBlock().next();
  59. //在第二行末尾添加
  60. cursor.setPosition(insert_block.position()+insert_block.length()-1);
  61. cursor.insertText("change cursor postion and insert");
  62. //在第三行开头添加-也就是新frame里面最开始添加
  63. //方法一,第二行末尾+1就是第三行开头
  64. cursor.setPosition(insert_block.position()+insert_block.length());
  65. //方法二,position默认返回的就是一个块开头
  66. cursor.setPosition(insert_block.next().position());
  67. //方法三,利用frame,frame是在一个锚点定位,开头在第二行末尾所以必须加一
  68. cursor.setPosition(frame_format.position()+1);
  69. cursor.insertText("change cursor postion and insert");
  70. }

前面的内容没有变化,后面先展示了如何遍历所有frame以及嵌套的frame。如果是全文检索或者整体修改也可以直接遍历全文所有block

转载请以链接形式标明本文标题和地址:Techie亮博客 » Qt富文本编辑器QTextDocument

Qt富文本编辑器QTextDocument的更多相关文章

  1. PyQt(Python+Qt)学习随笔:富文本编辑器QTextEdit功能详解

    专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 一.概述 QTextEdit是一个高级的所见即所得的文档查看器和编辑器 ...

  2. 在线富文本编辑器FckEditor配置(.Net Framework 3.5)

    进入FCKeditor文件夹,编辑 fckconfig.js 文件.1.上传设置  .  var _FileBrowserLanguage         = 'php' ;         // a ...

  3. 富文本编辑器Simditor的简易使用

    最近打算自己做一个博客系统,并不打算使用帝国cms或者wordpress之类的做后台管理!自己处于学习阶段也就想把从前台到后台一起谢了.好了,废话不多说了,先来看看富文本编辑器SimDitor,这里是 ...

  4. 个人网站对xss跨站脚本攻击(重点是富文本编辑器情况)和sql注入攻击的防范

    昨天本博客受到了xss跨站脚本注入攻击,3分钟攻陷--其实攻击者进攻的手法很简单,没啥技术含量.只能感叹自己之前竟然完全没防范. 这是数据库里留下的一些记录.最后那人弄了一个无限循环弹出框的脚本,估计 ...

  5. UEditor百度富文本编辑器--让编辑器自适应宽度的解决方案

    UEditor百度富文本编辑器的initialFrameWidth属性,默认值是1000. 不能够自适应屏幕宽度.如图1: 刚开始的时候,我是直接设置initialFrameWidth=null的.效 ...

  6. PHP Ueditor 富文本编辑器

    2016年12月11日 08:46:59 星期日 百度的简版富文本编辑器umeditor很久没更新了 全功能版本的配置项跟umeditor还是有区别的, 这里说下ueditor怎么对接到项目中去, 主 ...

  7. JavaScript 富文本编辑器

    WEB项目中使用UEditor(富文本编辑器) UEditor - 完整示例 http://ueditor.baidu.com/website/onlinedemo.html UEditor注意事项: ...

  8. MVC 使用 Ueditor富文本编辑器

    一.Ueditor 1.下载Ueditor富文本编辑器 官方下载地址: http://ueditor.baidu.com/website/download.html 建议下载开发版,此处我下载的是 . ...

  9. 富文本编辑器kindeditor配置

    <!--富文本编辑器kindeditor配置↓ --> <link type="text/css" rel="stylesheet" href ...

随机推荐

  1. 爬虫 Scrapy框架 爬取图虫图片并下载

    items.py,根据需求确定自己的数据要求 # -*- coding: utf-8 -*- # Define here the models for your scraped items # # S ...

  2. python爬虫同时输出两个列表(zip函数)

    简介:在做爬虫时,xpath返回的是列表格式,我们又需要将列表中的元素一一对应并存放至字典中,这是就可以用zip函数. zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组, ...

  3. C语言编程学习不难学,是你没找对方法!

    C语言是面向过程的,而C++是面向对象的 C和C++的区别: C是一个结构化语言,它的重点在于算法和数据结构.C程序的设计首要考虑的是如何通过一个过程,对输入(或环境条件)进行运算处理得到输出(或实现 ...

  4. [Golang学习笔记] 07 数组和切片

    01-06回顾: Go语言开发环境配置, 常用源码文件写法, 程序实体(尤其是变量)及其相关各种概念和编程技巧: 类型推断,变量重声明,可重名变量,类型推断,类型转换,别名类型和潜在类型 数组: 数组 ...

  5. 为树莓派添加一个强实时性前端[原创cnblogs.com/helesheng]

    树莓派是最近流行嵌入式平台,其自由的开源特性以及低廉的价格,吸引了来 自全球的大量极客和计算机大咖的关注.来自各大树莓派社区的幕后英雄,无私地在这个开源硬件平台上做了大量的工作,将其打造成了世界上通用 ...

  6. MySQL - CentOS 下 MySQL 5.6 安装

    1. 概述 最近没啥东西可写, 随便写点 mysql 5.6 的安装 去年写的 装上去过 三次以上 2. 准备 系统 CentOS 7.4 3. 安装 1. 直接安装 # mysql服务端: mysq ...

  7. #《JAVA程序设计》 20155214 实验五 网络编程与安全

    <JAVA程序设计> 20155214 实验五 网络编程与安全 实验内容 掌握Socket程序的编写: 掌握密码技术的使用: 设计安全传输系统. 实验要求 要求一 结对实现中缀表达式转后缀 ...

  8. 思维水题 poj1852

    题目链接:http://poj.org/problem?id=1852 题意:木板长为n,    蚂蚁数量为k,    后面k个数,依次代表蚂蚁的位置,  当蚂蚁到达边界的时候会立马掉下,当两个蚂蚁相 ...

  9. 百度地图Map属性和方法

    map的L属性:TANGRAM__1 map的F属性:[object Object] map的xa属性:[object HTMLDivElement] map的width属性:1340 map的hei ...

  10. XAF-物料管理信息工作日志

    前段时间已经开始了第一阶段验收了,客户方并未把重点放在业务流程上面,一直在调整一些界面问题.有点小纠结. 今天要调一下菜单位置. 没修改时,是这样的: 到了列表界面,会多一个全文检索出来. 后来,客户 ...