Qt中富文字處理相關類
1、QAbstractTextDocumentLayout:抽象基類,用於實現QTextDocuments的自定義佈局。Qt提供的標準佈局可以處理簡單的字處理,包括內聯影象、列表和表。有些應用程式,例如文書處理程式或DTP應用程式可能需要比Qt佈局引擎提供的功能更多的特性,在這種情況下,您可以子類化QAbstractTextDocumentLayout以為文字文件提供定製佈局行為。
2、QFont:指定用於繪製文字的字型。用於設定字型、大小、格式等
3、QSyntaxHighlighter:允許您定義語法高亮顯示規則,此外,您還可以使用該類查詢文件的當前格式或使用者資料
class Highlighter : public QSyntaxHighlighter { Q_OBJECT public: Highlighter(QTextDocument *parent = 0); protected: /* * 要提供自己的語法高亮顯示,必須子類化QSyntaxHighlighter並重新實現highlightBlock()。 * 在重新實現時,應該解析塊的文字,並根據需要經常呼叫setFormat()來應用所需的任何字型和顏色更改。 */ void highlightBlock(const QString &text) override; private: struct HighlightingRule { QRegularExpression pattern; QTextCharFormat format; }; QVector<HighlightingRule> highlightingRules;//存放高亮的各種規則 //使用正則表示式匹配 QRegularExpression commentStartExpression; QRegularExpression commentEndExpression; //字元的格式 QTextCharFormat keywordFormat; QTextCharFormat classFormat; QTextCharFormat singleLineCommentFormat; QTextCharFormat multiLineCommentFormat; QTextCharFormat quotationFormat; QTextCharFormat functionFormat; };
Highlighter::Highlighter(QTextDocument *parent) :QSyntaxHighlighter(parent) { HighlightingRule rule; keywordFormat.setForeground(Qt::darkBlue); keywordFormat.setFontWeight(QFont::Bold); QStringList keywordPatterns; keywordPatterns << "\\bchar\\b" << "\\bclass\\b" << "\\bconst\\b" << "\\bdouble\\b" << "\\benum\\b" << "\\bexplicit\\b" << "\\bfriend\\b" << "\\binline\\b" << "\\bint\\b" << "\\blong\\b" << "\\bnamespace\\b" << "\\boperator\\b" << "\\bprivate\\b" << "\\bprotected\\b" << "\\bpublic\\b" << "\\bshort\\b" << "\\bsignals\\b" << "\\bsigned\\b" << "\\bslots\\b" << "\\bstatic\\b" << "\\bstruct\\b" << "\\btemplate\\b" << "\\btypedef\\b" << "\\btypename\\b" << "\\bunion\\b" << "\\bunsigned\\b" << "\\bvirtual\\b" << "\\bvoid\\b" << "\\bvolatitle\\b" << "\\bbool\\b"; //儲存c++語法中的關鍵字的匹配規則 foreach (const QString& pattern, keywordPatterns) { rule.pattern = QRegularExpression(pattern); rule.format = keywordFormat; highlightingRules.append(rule); } //類名匹配規則以Q開頭的 classFormat.setFontWeight(QFont::Bold); classFormat.setForeground(Qt::darkMagenta); rule.pattern = QRegularExpression("\\bQ[A-Za-z]+\\b"); rule.format = classFormat; highlightingRules.append(rule); //有註釋的匹配規則 singleLineCommentFormat.setForeground(Qt::red); rule.pattern = QRegularExpression("//[^\n]*"); rule.format = singleLineCommentFormat; highlightingRules.append(rule); //多行註釋 multiLineCommentFormat.setForeground(Qt::red); //標頭檔案匹配規則 quotationFormat.setForeground(Qt::darkGreen); rule.pattern = QRegularExpression("\".*\""); rule.format = quotationFormat; highlightingRules.append(rule); //函式名稱匹配規則 functionFormat.setFontItalic(true); functionFormat.setForeground(Qt::blue); rule.pattern = QRegularExpression("\\b[A-Za-z0-9]+(?=\\()"); rule.format = functionFormat; highlightingRules.append(rule); //註釋開始的匹配 commentStartExpression = QRegularExpression("/\\*"); //註釋結束的匹配 commentEndExpression = QRegularExpression("\\*/"); } void Highlighter::highlightBlock(const QString &text) { foreach (const HighlightingRule &rule, highlightingRules) { //對文字進行正則表示式匹配 並返回匹配到的第一個匹配結果的迭代器 QRegularExpressionMatchIterator matchIterator = rule.pattern.globalMatch(text); while (matchIterator.hasNext()) { /* *QRegularExpressionMatch類提供了根據字串匹配QRegularExpression的結果。 */ QRegularExpressionMatch match = matchIterator.next(); qDebug() << text << " <<<>>>> " << match.capturedTexts(); //設定高亮的格式 setFormat(match.capturedStart(0) ,match.capturedEnd(0), rule.format); } } setCurrentBlockState(0); int startIndex = 0; if(previousBlockState() != 1) startIndex = text.indexOf(commentStartExpression); while (startIndex >= 0) { QRegularExpressionMatch match = commentEndExpression.match(text,startIndex); int endIndex = match.capturedStart(); int commentLength = 0; if(endIndex == -1){ setCurrentBlockState(1); commentLength = text.length() - startIndex; }else{ commentLength = endIndex - startIndex + match.capturedLength(); } setFormat(startIndex,commentLength,multiLineCommentFormat); startIndex = text.indexOf(commentStartExpression, startIndex+commentLength); } }
void MainWindow::setupEditor() { QFont font; font.setFamily("Courier"); font.setFixedPitch(true); font.setPointSize(10); editor = new QTextEdit; editor->setFont(font); //這裡先把自定義的註冊進去 告訴文件物件 使用這個進行高亮操作 hightlighter = new Highlighter(editor->document()); QFile file(":/src/mainwindow.h"); if(file.open(QIODevice::ReadOnly|QIODevice::Text)) editor->setPlainText(file.readAll()); else qDebug() << "11111"; }
4、QTextCursor:提供一個API來訪問和修改QTextDocuments
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
QTextEdit *textEdit = new QTextEdit(QString("hello world!hello Qt!"));
setCentralWidget(textEdit);
resize(400,300);
//先拿到游標物件
QTextDocument *doc = textEdit->document();
QTextCursor *cursor = new QTextCursor(doc);
qDebug() << "anchor=" << cursor->anchor() << " position=" << cursor->position();
qDebug() << "atBlockEnd=" << cursor->atBlockEnd() << " atBlockStart="<< cursor->atBlockStart();
qDebug() << "atEnd=" << cursor->atEnd() << " atStart="<< cursor->atStart();
//編輯操作
cursor->beginEditBlock();
cursor->insertText("This is ");
cursor->insertText("Insert ");
cursor->endEditBlock();
//返回游標所在的block的number
qDebug() << "blockNumber=" << cursor->blockNumber();
//返回游標所在行的列號
qDebug() << "columnNumber=" << cursor->columnNumber();
qDebug() << "hasComplexSelection=" << cursor->hasComplexSelection();
//返回是否選擇了內容
qDebug() << "hasSelection=" << cursor->hasSelection();
//在當前游標的位置插入一個空的block 相當於換行的操作
cursor->insertBlock();
//插入一個html文字
cursor->insertHtml("<font color='red'>insertHtml</font>");
cursor->insertBlock();
//插入一個圖片
cursor->insertImage(":/image/任務管理-我的任務-任務查詢查詢不到已經建立的任務.png");
qDebug() << "isNull=" << cursor->isNull();
cursor->insertBlock();
cursor->joinPreviousEditBlock();
cursor->insertHtml("</b><font color='blue'>joinPreviousEditBlock</font></b>");
cursor->endEditBlock();
qDebug() << "keepPositionOnInsert="<<cursor->keepPositionOnInsert();
//把游標移動到開頭
cursor->movePosition(QTextCursor::StartOfLine);
//移動游標不選擇
cursor->movePosition(QTextCursor::EndOfWord,QTextCursor::MoveAnchor);
//移動游標並且選擇移動範圍內的內容
cursor->movePosition(QTextCursor::EndOfLine,QTextCursor::KeepAnchor);
//介面要顯示出來需要設定一下
textEdit->setTextCursor(*cursor);
//游標在block中的位置
qDebug()<< "positionInBlock=" << cursor->positionInBlock() <<
" " << cursor->position()-cursor->block().position();
//刪除選中的文字
cursor->removeSelectedText();
//根據選中型別來選中文件中的內容
// cursor->select(QTextCursor::Document);
cursor->select(QTextCursor::WordUnderCursor);
//更新下游標 才能看出來是不是選中了
textEdit->setTextCursor(*cursor);
//返回選中的位置
qDebug() << "selectionStart=" << cursor->selectionStart()
<< " selectionEnd=" << cursor->selectionEnd();
//是否讓游標不隨著插入的文字移動,始終保持插入前的位置不變 預設是false
cursor->setKeepPositionOnInsert(false);
//使用m指定的MoveMode將游標移動到pos指定的文件中的絕對位置。游標位於字元之間。
cursor->setPosition(1,QTextCursor::MoveAnchor);
//更新
textEdit->setTextCursor(*cursor);
}
5、QTextDocument:核心類,儲存富文字資料
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
QTextEdit *edit = new QTextEdit;
QTextDocument *doc = edit->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::yellow);//設定背景色
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 = edit->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");
edit->setTextCursor(cursor);
//把內容遍歷出來
for(auto block=root_frame->begin();!block.atEnd(); ++block){
if(block.currentBlock().isValid()){
qDebug() << block.currentBlock().text();
}else if(block.currentFrame()){
qDebug() << "是一個框架";
for(auto frame_block = block.currentFrame()->begin(); !frame_block.atEnd(); ++frame_block){
if(frame_block.currentBlock().isValid()){
qDebug() << frame_block.currentBlock().text();
}else{
qDebug() << "else";
}
}
}
}
//遍歷所以block 包括每個frame中預設的空的
qDebug() << "doc->blockCount()=" << doc->blockCount();
QTextBlock block = doc->firstBlock();
for(int i = 0; i < doc->blockCount(); ++i){
qDebug()<< QString("block num:%1 block first line number:%2 block length:%3 text:")
.arg(i).arg(block.firstLineNumber()).arg(block.length())
<< block.text();
block = block.next();
}
//獲取第2個block的開頭
QTextBlock insert_block = doc->firstBlock().next();
cursor.setPosition(insert_block.position()+insert_block.length()-1);
cursor.insertText("change cursor postion and insert");
//將游標設定到第3個block的開頭
// cursor.setPosition(insert_block.position()+insert_block.length());
cursor.setPosition(insert_block.next().position());
cursor.insertText("change cursor postion and insert");
setCentralWidget(edit);
resize(400,300);
}
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
//先不用介面展示
QTextDocument *doc = new QTextDocument;
QTextCursor *cursor = new QTextCursor(doc);
//文件本身是有一個文字塊的 可以通過框架來獲得
QTextFrame *root_frame = doc->rootFrame();
QTextBlock block = root_frame->begin().currentBlock();
qDebug() << "此時文字塊="<<block.text();
//通過游標向文字塊中插入文字
cursor->insertText("aaa");
block = root_frame->begin().currentBlock();
qDebug() << "插入後的文字塊="<<block.text();
//插入一個新的文字塊 游標換行了 然後在此block中插入資料
cursor->insertBlock();
cursor->insertText("bbbb");
for(int i = 0; i < 10; ++i){
cursor->insertText("cccccccccccccccccccc");
}
qDebug() << "第2個block的長度="<<root_frame->begin().currentBlock().next().length();
qDebug() << "第2個block的行數="<<root_frame->begin().currentBlock().next().lineCount();
qDebug() << "第2個block的blockNumber="<<root_frame->begin().currentBlock().next().blockNumber();
//插入一個自定義的frame 插入之後 除了frame自帶一個block,在frame的最後還有一個blcok
QTextFrameFormat format = root_frame->frameFormat();
format.setBorder(3);
cursor->insertFrame(format);
cursor->setPosition(root_frame->begin().currentBlock().next().next().position());
cursor->insertText("dddd");
cursor->setPosition(root_frame->begin().currentBlock().next().next().next().position());
cursor->insertText("eeee");
qDebug() << doc->blockCount();
QTextEdit *edit = new QTextEdit;
edit->setDocument(doc);
edit->setTextCursor(*cursor);
setCentralWidget(edit);
resize(300,200);
}
6、QTextDocumentFragment:表示來自QTextDocument的富文字的片段,可以將該片段通過cursor插入到文件中去,並且只有當文件中的某個內容被選中時,可以通過獲取選中的片段來解析獲取選中的內容
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
QTextDocument *doc = new QTextDocument;
QTextCursor *cursor = new QTextCursor(doc);
QTextDocumentFragment fragment = QTextDocumentFragment::fromPlainText("hello world");
//向文件中插入片段
cursor->insertFragment(fragment);
//獲取選中的片段
cursor->select(QTextCursor::Document);
qDebug() << cursor->selection().toPlainText();
cursor->clearSelection();
cursor->insertBlock();
fragment = QTextDocumentFragment::fromHtml("<font color='red'>hello Qt</font>");
cursor->insertFragment(fragment);
cursor->select(QTextCursor::LineUnderCursor);
qDebug() << cursor->selection().toHtml();
cursor->clearSelection();
QTextEdit *edit = new QTextEdit;
edit->setDocument(doc);
edit->setTextCursor(*cursor);
setCentralWidget(edit);
}
7、QTextDocumentWriter:與格式無關的介面,用於將QTextDocument寫入檔案或其他裝置
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
//獲取支援的寫入格式
qDebug() << QTextDocumentWriter::supportedDocumentFormats();//("HTML", "ODF", "plaintext")
QTextDocumentWriter writer("a.txt");
QTextCodec* gb2312Codec = QTextCodec::codecForName("gb2312");
writer.setCodec(gb2312Codec);
writer.write(QTextDocumentFragment::fromPlainText("你好啊"));
//把寫入的檔案讀出來
QFile file("a.txt");
file.open(QIODevice::ReadOnly);
QByteArray array = file.readAll();
qDebug() << gb2312Codec->toUnicode(array);
QTextDocumentWriter writerOdf("a.doc","odf");//xlsx xls 試下了 好像不行 有可能方法錯了
writerOdf.write(QTextDocumentFragment::fromPlainText("你好啊"));
QTextDocumentWriter writerHtml("a.html","HTML");
writerHtml.write(QTextDocumentFragment::fromHtml("<b><font color='red'>你好啊</font></b>"));
}
8、QTextBlockFormat: 儲存QTextDocument中的文字塊的格式資訊。
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
QTextDocument *doc = new QTextDocument;
QTextCursor *cursor = new QTextCursor(doc);
//自定義一個blcok格式
QTextBlockFormat blockFormat;
blockFormat.setAlignment(Qt::AlignRight);//右對齊
blockFormat.setBackground(QBrush(Qt::yellow));//背景色
blockFormat.setBottomMargin(10);//外部距離底部的空間
blockFormat.setForeground(QBrush(Qt::lightGray));//前景色
blockFormat.setIndent(4);//縮排
blockFormat.setLayoutDirection(Qt::RightToLeft);//文字從右到左
blockFormat.setLeftMargin(10);//外部距離左邊的空間
blockFormat.setLineHeight(50,QTextBlockFormat::LineDistanceHeight);//這將在行之間新增指定的高度50畫素點
blockFormat.setNonBreakableLines(true);//設定是不可以被打亂的
blockFormat.setTopMargin(50);
blockFormat.setRightMargin(100);
blockFormat.setTextIndent(10);//為塊中的第一行設定縮排。
cursor->insertBlock(blockFormat);
cursor->insertText("這幾天權健新聞火了,昔日風光無比的保健品大拿,今日面臨著各項指控,高法還指認其進涉嫌傳銷,可嘆法網恢恢疏而不漏啊。今天做生意,講的是商業模式,網際網路的發展形成了很多種商業模式,比如社交,比如B2B,B2C等,但是,在網際網路大行其道之前,中國常看到的就是一種直銷的商業模式,直銷接著就出來變種,變成了傳銷,直銷和傳銷都是拉人頭,只不過直銷還是有商品為主,而傳銷感覺商品只是其中一個引子而已,純粹就是賺人頭費,層層的組織,最終讓人們死心塌地活在傳銷生態圈裡不能自拔,曾幾何時,見面就跟人談產品,讓人無比側目。");
cursor->insertBlock(QTextBlockFormat());
cursor->insertText("這個是正常的");
QTextEdit *edit = new QTextEdit;
edit->setDocument(doc);
edit->setTextCursor(*cursor);
setCentralWidget(edit);
resize(500,400);
}
9、QTextCharFormat:儲存QTextDocument中的字元的格式資訊。
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
QTextEdit *edit = new QTextEdit;
QTextDocument *doc = edit->document();
QTextCursor *cursor = new QTextCursor(doc);
//自定義一個型別
QTextCharFormat charFormat;
charFormat.setAnchorHref("http://example.com/index.html");
charFormat.setAnchor(true);
QFont font;
font.setBold(true);
font.setUnderline(true);
charFormat.setFont(font);
charFormat.setToolTip("這是hello world");
cursor->insertBlock();
cursor->insertText("hello world",charFormat);
edit->setTextCursor(*cursor);
setCentralWidget(edit);
resize(400,100);
}
10、QTextFormat:儲存QTextDocument中文字的格式資訊。QTextFormat是一個通用類,用於描述QTextDocument部分內容的格式。派生類QTextCharFormat、QTextBlockFormat、QTextListFormat和QTextTableFormat通常更有用,它們描述了應用於文件特定部分的格式。
11、QTextFrameFormat:儲存QTextDocument中的框架的格式資訊。
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
QTextEdit *edit = new QTextEdit;
QTextDocument *doc = edit->document();
QTextCursor *cursor = new QTextCursor(doc);
cursor->insertText("這是我的框架格式");
cursor->insertBlock();
//自定義格式
QTextFrameFormat format;
format.setBackground(QBrush(Qt::blue));
format.setBorder(3);
format.setBorderBrush(QBrush(Qt::red));
format.setTopMargin(5);
format.setBottomMargin(5);
format.setLeftMargin(5);
format.setRightMargin(5);
// format.setHeight(QTextLength(QTextLength::FixedLength,100));
format.setPadding(30);
format.setPosition(QTextFrameFormat::FloatRight);
format.setWidth(QTextLength(QTextLength::PercentageLength,40));
format.setBorderStyle(QTextFrameFormat::BorderStyle_Dotted);
cursor->insertFrame(format);
cursor->insertText("啊啊啊啊啊啊啊");
setCentralWidget(edit);
edit->setTextCursor(*cursor);
resize(400,300);
}
這張圖特別形象說明了文字或者框架的圍繞佈局
12、QTextImageFormat:儲存QTextDocument中的影象的格式資訊。
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
QTextDocument *doc = new QTextDocument;
QTextCursor *cursor = new QTextCursor(doc);
//自定義一個圖片格式
QTextImageFormat imageFormat;
QImage image(":/image/v2-e687e8a3299301852036625042c0d21f_hd.jpg");
imageFormat.setName(":/image/v2-e687e8a3299301852036625042c0d21f_hd.jpg");
imageFormat.setHeight(image.height()*0.3);
imageFormat.setWidth(image.width()*0.3);
cursor->insertBlock();
cursor->insertImage(imageFormat);
QTextEdit *edit = new QTextEdit;
edit->setDocument(doc);
edit->setTextCursor(*cursor);
setCentralWidget(edit);
resize(400,300);
}
13、QTextLength:表示了QTextDocument中不同型別的文字長度。使用方法詳見上面
14、QTextListFormat:儲存QTextDocument中的列表的格式資訊。
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
QTextEdit *edit = new QTextEdit;
QTextDocument *doc = edit->document();
QTextCursor *cursor = new QTextCursor(doc);
cursor->beginEditBlock();
cursor->insertText("hello world");
cursor->insertText("aaaa");
cursor->endEditBlock();
QTextBlock listblock = cursor->block();
cursor->insertBlock();
cursor->setPosition(listblock.length()-1);
//定義一個TextListFormat
QTextListFormat format;
format.setBackground(QBrush(Qt::blue));
format.setIndent(1);//設定縮排
format.setLayoutDirection(Qt::RightToLeft);//設定文字方向
format.setStyle(QTextListFormat::ListDecimal);//設定開頭以數字表示
format.setNumberPrefix("(");//字首
format.setNumberSuffix(")");//字尾
QTextList *list = cursor->insertList(format);
cursor->insertText("bbbb");
//但是如何跳出這個textlist呢?
cursor->setPosition(cursor->block().next().position());
edit->setTextCursor(*cursor);
setCentralWidget(edit);
resize(300,200);
}
15、QTextTableCellFormat:儲存QTextDocument中的表格單元的格式資訊
16、QTextTableFormat:儲存QTextDocument中的表格的格式資訊
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
QTextDocument *doc = new QTextDocument;
QTextCursor cursor = QTextCursor(doc);
cursor.insertText("hello world");
//根據表格式來建立表
QTextTableFormat tableFormat;
tableFormat.setBackground(QBrush(Qt::yellow));
tableFormat.setBorder(2);
tableFormat.setBorderStyle(QTextFrameFormat::BorderStyle_Solid);
//表格的對齊方式 注意不是表格內的內容
tableFormat.setAlignment(Qt::AlignCenter);
tableFormat.setPadding(2);
tableFormat.setCellSpacing(3);
cursor.insertTable(10,4,tableFormat);
QTextEdit *edit = new QTextEdit;
edit->setDocument(doc);
edit->setTextCursor(cursor);
setCentralWidget(edit);
resize(300,200);
}
17、QTextInlineObject:表示QAbstractTextDocumentLayout及其實現中的內聯物件。通常,您不需要建立QTextInlineObject。QAbstractTextDocumentLayout在實現自定義佈局時使用它來處理內聯物件。
18、QTextLayout:用於佈局和呈現文字。QTextLayout可用於建立具有給定寬度的QTextLine例項序列,並可在螢幕上獨立定位它們。一旦佈局完成,這些線條就可以繪製在繪圖裝置上。
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
resize(300,200);
}
MainWindow::~MainWindow()
{
}
void MainWindow::paintEvent(QPaintEvent *event)
{
QTextLayout *layout = new QTextLayout;
//要進行佈局的文字內容
layout->setText("hello world 11111111111111111111111111111111");
//一般設定可以快取
layout->setCacheEnabled(true);
//更改下文字的字型格式
QFont font;
font.setUnderline(true);
layout->setFont(font);
//開始佈局
layout->beginLayout();
int height = 0;
int lineWidth = 100;
int startPoint = 0;
while (1) {
//先建立一個行
QTextLine line = layout->createLine();
if (!line.isValid())
break;
//設定這一行的文字寬度
line.setLineWidth(lineWidth);
//高度需要疊加計算 否則文字會被佈局到一起
height += 10;
//設定行的起點和高度
line.setPosition(QPointF(30*(++startPoint), height));
//計算最終的高度
height += line.height();
}
layout->endLayout();
QPainter painter(this);
layout->draw(&painter, QPoint(0, 50));
}
19、QTextLine:表示QTextLayout中的一行文字。
20、QTextList:提供QTextDocument中修飾過的專案列表。
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
QTextEdit *edit = new QTextEdit;
QTextDocument *doc = edit->document();
QTextCursor *cursor = new QTextCursor(doc);
cursor->insertText("hello world");
//有2中建立QTextList的方式
//createList函式:獲取游標當前block的內容,並將其轉換為新列表的第一項。
cursor->createList(QTextListFormat::ListDisc);
cursor->insertText("aaaa");
//繼續在此列表中新增資料
cursor->insertBlock();
cursor->insertText("bbbb");
//insertList函式:在文件的游標位置插入一個block,並將其作為列表中的第一項。
cursor->insertList(QTextListFormat::ListCircle);
cursor->insertText("hello Qt");
cursor->insertBlock();
cursor->insertText("cccc");
edit->setTextCursor(*cursor);
setCentralWidget(edit);
resize(400,300);
}
21、QTextBlock:為QTextDocument中的文字片段提供了一個容器。
22、QTextBlockGroup:為QTextDocument中的文字塊提供了一個容器。
23、QTextBlockUserData:將自定義資料與文字塊相關聯。
24、QTextFragment:使用一個QTextCharFormat儲存QTextDocument中的一段文字。
25、QTextFrame:表示QTextDocument中的一個框架。
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
QTextEdit *edit = new QTextEdit;
QTextDocument *doc = edit->document();
QTextCursor *cursor = new QTextCursor(doc);
cursor->insertText("aaaa");
cursor->insertBlock();
//必須先定義一個框架格式
QTextFrameFormat frameFormat;
frameFormat.setBorder(3);
//建立在文件中新增框架
QTextFrame *frame = cursor->insertFrame(frameFormat);
cursor->insertText("bbbb");
frameFormat.setBorder(2);
frameFormat.setBorderBrush(QBrush(Qt::red));
frameFormat.setBorderStyle(QTextFrameFormat::BorderStyle_Dotted);
QTextFrame *childFrame = cursor->insertFrame(frameFormat);
cursor->insertText("cccc");
qDebug()<< "子框架個數:"<<frame->childFrames().size();
cursor->setPosition(cursor->block().next().position());
cursor->insertText("dddd");
//返回框架中的第一個游標位置。
QTextCursor frameCursor = childFrame->parentFrame()->firstCursorPosition();
edit->setTextCursor(frameCursor);
//返回框架中的最後的游標位置。
frameCursor = childFrame->parentFrame()->lastCursorPosition();
edit->setTextCursor(frameCursor);
setCentralWidget(edit);
// edit->setTextCursor(*cursor);
resize(300,200);
}
26、QTextObject:用於不同型別物件的基類,這些物件可以將QTextDocument的各個部分組合在一起。
27、QTextFrame::iterator: 迭代器類為讀取QTextFrame的內容提供了一個迭代器。
28、QTextBlock::iterator: 為讀取QTextBlock的內容提供了一個迭代器。
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
QTextEdit *edit = new QTextEdit;
QTextDocument *doc = edit->document();
QTextCursor cursor = edit->textCursor();
cursor.insertText("hello world! hello Qt!");
cursor.insertText("111222333444");
QTextBlock block = cursor.block();//doc->firstBlock();
QTextBlock::iterator it;
for(it = block.begin(); !it.atEnd(); ++it){
QTextFragment fragment = it.fragment();
if(fragment.isValid())
qDebug() << fragment.text();
}
setCentralWidget(edit);
edit->setTextCursor(cursor);
resize(300,200);
}
29、QTextOption:可以設定富文字的一般屬性。
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
QTextEdit *edit = new QTextEdit;
QTextDocument *doc = edit->document();
doc->setPlainText("hello world!111111");
//定義一個封裝文字格式的物件
QTextOption option;
// option.setAlignment(Qt::AlignCenter);
option.setTextDirection(Qt::RightToLeft);
option.setWrapMode(QTextOption::WrapAnywhere);
doc->setDefaultTextOption(option);
setCentralWidget(edit);
resize(300,200);
}
30、QTextTable:表示QTextDocument中的一個表。
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
QTextEdit *edit = new QTextEdit;
QTextDocument *doc = edit->document();
QTextCursor cursor = edit->textCursor();
cursor.insertText("hello world");
//不含表格式建立 游標落在第一行第一列中
QTextTable *table = cursor.insertTable(5,5);
//右側插入2列
table->insertColumns(4,2);
//下邊插入2行
table->insertRows(4,2);
//合併單元格 指定下標
table->mergeCells(0,0,2,5);
cursor.insertText("合併000000000000000000000000");
//合併單元格 合併由提供的遊標選擇的單元格。
cursor.movePosition(QTextCursor::NextRow);
cursor.movePosition(QTextCursor::NextCell,QTextCursor::KeepAnchor);
table->mergeCells(cursor);
cursor.insertText("合併111111111111111111111111");
//將個單元格分割成多行多列 只可能分割跨多個行或列的單元格,例如使用mergeCells()合併的行。
table->splitCell(0,0,1,2);
//設定一個空的格式
table->setFormat(QTextTableFormat());
//游標如何跳出這個表
// for(int i = 1; i < table->rows(); ++i)
// cursor.movePosition(QTextCursor::NextRow);
// for(int i = 1; i < table->columns(); ++i)
// cursor.movePosition(QTextCursor::NextCell);
// cursor.movePosition(QTextCursor::NextBlock);
// cursor.insertBlock();
// cursor.insertText("aaaa");
setCentralWidget(edit);
edit->setTextCursor(cursor);
resize(300,200);
}
31、QTextTableCell:表示QTextTable中的單元格的屬性。
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
resize(300,200);
QTextEdit *edit = new QTextEdit;
QTextDocument *doc = edit->document();
QTextCursor cursor = edit->textCursor();
QVector<QTextLength> vector;
for(int i = 0; i < 5; ++i)
vector << QTextLength(QTextLength::PercentageLength,20);
QTextTableFormat format;
format.setColumnWidthConstraints(vector);
format.setCellSpacing(1);
QTextTable *table = cursor.insertTable(5,5,format);
//賦值
for(int i = 0; i < 5; ++i){
for(int j = 0; j < 5; ++j){
//設定下字型格式
QTextBlockFormat blockFormat;
blockFormat.setAlignment(Qt::AlignRight);
cursor.setBlockFormat(blockFormat);
QTextCharFormat charFormat;
charFormat.setFontFamily("宋體");
charFormat.setFontItalic(true);
charFormat.setFontUnderline(true);
cursor.setCharFormat(charFormat);
cursor.insertText(QString("row%1,col%2").arg(i).arg(j));
QTextTableCell cell = table->cellAt(cursor);
qDebug() << "(" << cell.row() << "," << cell.column() << ")";
QTextCursor tmp = cell.firstCursorPosition();
qDebug() << "first tmp = " << tmp.position();
tmp = cell.lastCursorPosition();
qDebug() << "last tmp = " << tmp.position();
if(j == 4)
continue;
cursor.movePosition(QTextCursor::NextCell);
}
if(i == 4)
continue;
cursor.movePosition(QTextCursor::NextRow);
}
edit->setTextCursor(cursor);
setCentralWidget(edit);
}
32、QPlainTextDocumentLayout:為QTextDocument實現純文字佈局
33、QPlainTextEdit:一個小部件,用於編輯和顯示純文字。
class LineNumberArea;
class CodeEditor : public QPlainTextEdit
{
Q_OBJECT
public:
CodeEditor(QWidget *parent = 0);
~CodeEditor();
void lineNumberAreaPaintEvent(QPaintEvent *event);
int lineNumberAreaWidth();
protected:
void resizeEvent(QResizeEvent *event) override;
private slots:
void updateLineNumberAreaWidth(int newBlockCount);
void highlightCurrentLine();
void updateLineNumberArea(const QRect & , int);
private:
QWidget *lineNumberArea;
};
class LineNumberArea : public QWidget
{
public:
LineNumberArea(CodeEditor *editor):QWidget(editor)
{
codeEditor = editor;
}
QSize sizeHint()const override
{
return QSize(codeEditor->lineNumberAreaWidth(),0);
}
protected:
void paintEvent(QPaintEvent *event) override
{
codeEditor->lineNumberAreaPaintEvent(event);
}
private:
CodeEditor *codeEditor;
};
CodeEditor::CodeEditor(QWidget *parent)
: QPlainTextEdit(parent)
{
//建立行號顯示控制元件
lineNumberArea = new LineNumberArea(this);
//當換行時更新行號
connect(this,SIGNAL(blockCountChanged(int)),
this,SLOT(updateLineNumberAreaWidth(int)));
connect(this,SIGNAL(updateRequest(QRect,int)),
this,SLOT(updateLineNumberArea(QRect,int)));
connect(this,SIGNAL(cursorPositionChanged()),
this, SLOT(highlightCurrentLine()));
updateLineNumberAreaWidth(0);
highlightCurrentLine();
}
CodeEditor::~CodeEditor()
{
}
void CodeEditor::lineNumberAreaPaintEvent(QPaintEvent *event)
{
qDebug() << event->rect();
QPainter painter(lineNumberArea);
painter.fillRect(event->rect(),Qt::lightGray);
QTextBlock block = firstVisibleBlock();
int blockNumber = block.blockNumber();
int top = (int)blockBoundingGeometry(block).translated(contentOffset()).top();
int bottom = top + (int)blockBoundingRect(block).height();
while (block.isValid() && top <= event->rect().bottom()) {
if(block.isVisible() && bottom >= event->rect().top()){
QString number = QString::number(blockNumber+1);
painter.setPen(Qt::black);
painter.drawText(0,top,lineNumberArea->width(),fontMetrics().height(),
Qt::AlignRight,number);
}
block = block.next();
top = bottom;
bottom = top + (int)blockBoundingRect(block).height();
++blockNumber;
}
}
int CodeEditor::lineNumberAreaWidth()
{
int digits = 1;
int max = qMax(1,this->blockCount());
while (max >= 10) {
max /= 10;
++digits;
}
int space = 3+fontMetrics().width(QLatin1Char('9'))*digits;
return space;
}
void CodeEditor::resizeEvent(QResizeEvent *event)
{
QPlainTextEdit::resizeEvent(event);
QRect cr = contentsRect();
lineNumberArea->setGeometry(QRect(cr.left(),
cr.top(),lineNumberAreaWidth(),
cr.height()));
}
void CodeEditor::updateLineNumberAreaWidth(int newBlockCount)
{
//更新編輯框距離左邊的間距
setViewportMargins(lineNumberAreaWidth(),0,0,0);
}
void CodeEditor::highlightCurrentLine()
{
QList<QTextEdit::ExtraSelection> extraSelections;
if(!isReadOnly()){
//ExtraSelection結構提供了一種為文件中給定的選擇指定字元格式的方法
QTextEdit::ExtraSelection selection;
QColor lineColor = QColor(Qt::yellow).lighter(160);
selection.format.setBackground(lineColor);
//FullWidthSelection 表示在選定的字元格式上設定時,將顯示選定文字的整個寬度。
selection.format.setProperty(QTextFormat::FullWidthSelection,true);
selection.cursor = textCursor();
selection.cursor.clearSelection();
extraSelections.append(selection);
}
/*
* 此函式允許用指定的顏色(指定為選擇)臨時標記文件中的某些區域。這可能非常有用,
* 例如在程式設計編輯器中,用給定的背景顏色標記一整行文字以表明斷點的存在。
*/
setExtraSelections(extraSelections);
}
void CodeEditor::updateLineNumberArea(const QRect &rect, int dy)
{
qDebug() << rect << " "<<dy;
if(dy){
//讓行號跟隨編輯框滾動 並且重新繪製
lineNumberArea->scroll(0,dy);
}else{
lineNumberArea->update(0,rect.y(),lineNumberArea->width(),rect.height());
}
if(rect.contains(viewport()->rect()))
updateLineNumberAreaWidth(0);
}
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
QPlainTextEdit *edit = new QPlainTextEdit("hello world111222333");
//設定換行格式
// edit->setLineWrapMode(QPlainTextEdit::NoWrap);//不換行
edit->setWordWrapMode(QTextOption::WrapAnywhere);//任意處換行
//插入文字 在當前游標前面
edit->insertPlainText("555666");
//追加文字 在文件最後 並且換行追加
edit->appendPlainText("777888");
edit->appendPlainText("999000");
//查詢並且選中文字
QTextCursor cursor = edit->textCursor();
edit->find("888");
setCentralWidget(edit);
resize(300,200);
}
34、QTextBrowser:提供了具有超文字導航的富文字瀏覽器。
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
QTextBrowser *browser = new QTextBrowser;
browser->setAttribute(Qt::WA_DeleteOnClose);
setCentralWidget(browser);
//可以當做編輯框使用
// browser->setReadOnly(false);
// browser->setEnabled(true);
/*
* 指定QTextBrowser是否應該使用QDesktopServices::openUrl()自動開啟指向外部源的連結,
* 而不是發出錨點單擊訊號。如果連結的模式既不是檔案也不是qrc,則視為外部連結.
*/
browser->setOpenExternalLinks(true);//設定為支援使用外部程式開啟url
/*
* 此屬性指定QTextBrowser是否應自動開啟使用者試圖通過滑鼠或鍵盤啟用的連結。
*/
browser->setOpenLinks(true);
/*
* 此屬性儲存文字瀏覽器用於查詢支援內容的搜尋路徑
* QTextBrowser使用這個列表來定點陣圖像和文件。
*/
browser->setSearchPaths(QStringList()<<"F:/");
/*
* 此屬性儲存顯示的文件的名稱。
* QTextBrowser嘗試在當前源的searchPaths屬性和目錄的路徑中查詢具有指定名稱的文件,
* 除非該值是一個絕對檔案路徑。
*/
//載入一個下載好的html來供文字瀏覽器使用
QUrl url = QUrl::fromLocalFile("F:/【wei375653972的部落格】Qt基礎學習_成為QML大神_Qt常用類學習 - CSDN部落格.html");
browser->setSource(url);
/*
* 請注意,瀏覽器將自動處理到link指定位置的導航,除非將openLinks屬性設定為false,
* 或者在連線的槽中呼叫setSource()。此機制用於覆蓋瀏覽器的預設導航特性。
*/
connect(browser,&QTextBrowser::anchorClicked,[=](const QUrl &){
qDebug() << url.url();
});
home = menuBar()->addAction("Home");
connect(home,&QAction::triggered,browser,&QTextBrowser::home);
back = menuBar()->addAction("Back");
connect(back,&QAction::triggered,browser,&QTextBrowser::backward);
close = menuBar()->addAction("Close");
connect(close,&QAction::triggered,browser,&QTextBrowser::close);
connect(browser,&QTextBrowser::destroyed,[=]{
qDebug() << "被銷燬了?";
});
}
35、QTextEdit:一個小部件,用於編輯和顯示純文字和富文字。詳見上面