1. 介绍
对于文本编辑,qt提供了不少控件html
- 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 Processingwindows
QTextEdit和QPlainTextEdit选择:差别是QTextEdit提供了tohtml,若是想在处理完文档,直接根据文档生成html做为博客等内容,能够使用此类,没有须要后者便可api
注意关系:QTextDocument>QTextFrame>QTextBlock/QTextTable/QTextList前包含后app
查看两个类的api,均提供了document方法,能够返回QTextDocument指针,用于经过QTextDocument的方式操做文档内容格式,官方范例:框架
Application Example这个比较简单编辑器
Syntax Highlighter Example语法高亮的例子函数
Text Edit Example相似于word编辑器的例子布局
Calendar Example利用富文本编辑器的方式实现日历(不建议学这个毕竟已经有现成的日历控件,并且文档中每每也不会插入日历)post
Order Form Example根据一些的参数设置生成报表,其实和上面的原理同样优化
2. 基本使用
首先当具备一个edit时,不须要自行建立document,能够直接用document方法能够获取当前edit的document
QTextDocument只是一个文档,其内还有根节点,须要使用QTextDocument::rootFlrame获取,设置根节点的边框粗细、颜色就相似于设置word文档边框底纹
2.1. 简单范例
- #include "mainwindow.h"
- #include "ui_mainwindow.h"
- #include <QTextDocument>
- #include <QTextFrame>
- #include <QTextBlock>
- MainWindow::MainWindow(QWidget *parent) :
- QMainWindow(parent),
- ui(new Ui::MainWindow) {
- ui->setupUi(this);
- QTextDocument* doc = ui->textEdit->document();
- QTextFrame *root_frame = doc->rootFrame();
- QTextFrameFormat root_frame_format = root_frame->frameFormat();//建立框架格式
- root_frame_format.setBorderBrush(Qt::darkBlue);//设置边界颜色
- root_frame_format.setBorder(5);//设置边界宽度
- root_frame->setFrameFormat(root_frame_format); //给框架使用格式
- QTextFrameFormat frame_format;
- frame_format.setBackground(Qt::darkRed);//设置背景色
- frame_format.setMargin(10);//设置边距
- frame_format.setPadding(5);//设置填充
- frame_format.setBorder(2);//设置边界宽度
- frame_format.setBorderStyle(
- QTextFrameFormat::BorderStyle_Solid);//设置边框样式
- frame_format.setPosition(QTextFrameFormat::FloatRight);//右侧
- frame_format.setWidth(QTextLength(
- QTextLength::PercentageLength, 40));//宽度设置
- QTextCursor cursor = ui->textEdit->textCursor();
- cursor.insertText("A company");
- cursor.insertBlock();
- cursor.insertText("321 City Street");
- cursor.insertBlock();
- cursor.insertFrame(frame_format);
- cursor.insertText("Industry Park");
- cursor.insertBlock();
- cursor.insertText("Another country");
- }
上述代码仅显示了四行文字,前两行在root跟框架显示,后两行在一个新建的frame中显示,并将frame置于右侧限定了宽度,更多的布局方法请参考:Order Form Example
上述并未对文本格式作设置,能够在insertText的第二个参数直接赋予一个文本格式QTextCharFormat
2.2. QTextCursor光标操做/遍历嵌套Frame/遍历全部Block
首先他有各类instert函数能够插入上面提到的各类文档中的数据类型。有时并不能一次准确的创建好整个文档,须要在中间插入,这样就须要setPosition命令,而positon的具体值能够经过上述各类数据类型的类获取到每一个块或者框架或者其余类型开头的positon,也能够经过length获取到当前块的长度用于定位末尾位置。下面提供一个简单范例
- #include "mainwindow.h"
- #include "ui_mainwindow.h"
- #include <QTextDocument>
- #include <QTextFrame>
- #include <QTextBlock>
- #include <QDebug>
- MainWindow::MainWindow(QWidget *parent) :
- QMainWindow(parent),
- ui(new Ui::MainWindow) {
- ui->setupUi(this);
- QTextDocument* doc = ui->textEdit->document();
- QTextFrame *root_frame = doc->rootFrame();
- QTextFrameFormat root_frame_format = root_frame->frameFormat();//建立框架格式
- root_frame_format.setBorderBrush(Qt::darkBlue);//设置边界颜色
- root_frame_format.setBorder(5);//设置边界宽度
- root_frame->setFrameFormat(root_frame_format); //给框架使用格式
- QTextFrameFormat frame_format;
- frame_format.setBackground(Qt::darkRed);//设置背景色
- frame_format.setMargin(10);//设置边距
- frame_format.setPadding(5);//设置填充
- frame_format.setBorder(2);//设置边界宽度
- frame_format.setBorderStyle(
- QTextFrameFormat::BorderStyle_Solid);//设置边框样式
- frame_format.setPosition(QTextFrameFormat::FloatRight);//右侧
- frame_format.setWidth(QTextLength(
- QTextLength::PercentageLength, 40));//宽度设置
- QTextCursor cursor = ui->textEdit->textCursor();
- cursor.insertText("A company");
- cursor.insertBlock();
- cursor.insertText("321 City Street");
- cursor.insertFrame(frame_format);
- cursor.insertText("Industry Park");
- cursor.insertBlock();
- cursor.insertText("Another country");
- //遍历frame
- for(auto block = root_frame->begin();!block.atEnd();++block) {
- if(block.currentBlock().isValid()) {
- qDebug()<<block.currentBlock().text();
- }
- else if(block.currentFrame()) {//frame嵌套,范例只有两层因此不递归了
- auto child_frame = block.currentFrame();
- for(auto block2 = child_frame->begin();!block2.atEnd();++block2) {
- if(block.currentBlock().isValid()) {
- qDebug()<<block2.currentBlock().text();
- }
- }
- }
- }
- //还能够经过root_frame->childFrames()直接获取所字frame
- //遍历文本块
- QTextBlock block = doc->firstBlock();
- for(int i = 0; i < doc->blockCount();i++) {
- qDebug() << QString("block num:%1\tblock first line number:%2\tblock length:%3\ttext:")
- .arg(i).arg(block.firstLineNumber()).arg(block.length())
- << block.text();
- block = block.next();
- }
- QTextBlock insert_block = doc->firstBlock().next();
- //在第二行末尾添加
- cursor.setPosition(insert_block.position()+insert_block.length()-1);
- cursor.insertText("change cursor postion and insert");
- //在第三行开头添加-也就是新frame里面最开始添加
- //方法一,第二行末尾+1就是第三行开头
- cursor.setPosition(insert_block.position()+insert_block.length());
- //方法二,position默认返回的就是一个块开头
- cursor.setPosition(insert_block.next().position());
- //方法三,利用frame,frame是在一个锚点定位,开头在第二行末尾因此必须加一
- cursor.setPosition(frame_format.position()+1);
- cursor.insertText("change cursor postion and insert");
- }
前面的内容没有变化,后面先展现了如何遍历全部frame以及嵌套的frame。若是是全文检索或者总体修改也能够直接遍历全文全部block