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