Qt富文本編輯器QTextDocument
本文標題:Qt富文本編輯器QTextDocument 本文地址:http://techieliang.com/2017/12/726/ 文章目錄
- 1. 介紹
- 2. 基本使用
- 2.1. 簡單範例
- 2.2. QTextCursor光標操作/遍歷嵌套Frame/遍歷所有Block
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. 簡單範例
- #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
轉載請以鏈接形式標明本文標題和地址:Techie亮博客 » Qt富文本編輯器QTextDocument
Qt富文本編輯器QTextDocument