QTextEdit 总结
關(guān)于Qt的富文本處理, 可以參考文檔:?Rich Text Processing
該文檔有人翻譯了一下(本來我想翻譯- -!), 參考Rich Text Processing富文本處理?
QTextEdit的組成比較復(fù)雜, 最好看看文檔了解一下Rich Text Document Structure
1. HTML形式操縱Qtextedit
QTextEdit支持HTML的一個(gè)子集, 所以對(duì)于簡(jiǎn)單的使用, 可以直接插入HTML代碼
editor->append("<img src=\"mydata://image.png\" />");
通過插入html代碼, 可以實(shí)現(xiàn)圖片, 字體, 字號(hào), 顏色等功能
ps: QTextEdit中img標(biāo)簽僅支持src, width, height三個(gè)屬性, 使用其他屬性會(huì)自動(dòng)被Qt過濾掉, 即editor->toHtml()中無法找到
可以通過正則來過濾toHtml()生成的代碼
其他HTML支持, 參考Supported HTML Subset
2. 在QTextEdit中播放gif
QTextEdit雖然直接img標(biāo)簽, 但默認(rèn)不播放gif, 也不會(huì)顯示gif的第一幀 (如果你不需要編輯功能的話, 其實(shí)可以用QWebView來查看)
所以在QTextEdit中播放gif需要手動(dòng)換幀.?
QMovie內(nèi)置了gif解析和定時(shí)器功能.?
QTextDocument 使用addResource 把圖片資源加載進(jìn)來, 然后通過QMovie->start啟動(dòng)定時(shí)器, 不斷更新圖片資源
QString g_fileName = ":/test.gif"; QUrl g_url("TestImageTag"); void MyClass::InsertImage() {QMovie* movie = new QMovie(this); movie->setFileName(g_fileName); movie->setCacheMode(QMovie::CacheNone); //換幀時(shí)刷新 connect(movie, SIGNAL(frameChanged(int)), this, SLOT(OnAnimate(int))); movie->start(); }g_url 是自定義的標(biāo)簽, 用來標(biāo)記QTextDocument 中的resource
void MyClass::OnAnimate(int a) { if (QMovie* movie = qobject_cast<QMovie*>(sender())) { document()->addResource(QTextDocument::ImageResource, //替換圖片為當(dāng)前幀 g_url, movie->currentPixmap()); setLineWrapColumnOrWidth(lineWrapColumnOrWidth()); // 刷新顯示 } }addResource 指定ImageResource,?然后根據(jù)url, 若url已存在, 則更新資源, 若url不存在, 則添加資源
這樣就實(shí)現(xiàn)刷新gif的幀. 這樣, QTextEdit就會(huì)顯示gif動(dòng)畫了
?
最后是添加gif圖片:
可以插入HTML:?
editor->append("<img src=\"TestImageTag\" />");即img中指定為我們自定義的url即可
也可以使用QTextCursor插入:
QTextCursor cursor = editor->textCursor(); QTextImageFormat imageFormat; imageFormat.setName("TestImageTag"); cursor.insertImage(imageFormat);PS: 可以使用兩個(gè)數(shù)組來保存自定義的URL和QMOVIE, 以便管理資源釋放等問題
PS2: 在我的測(cè)試中, 即使調(diào)用了Qtextedit和QTextDocument的clear也無法釋放addResource圖片資源的內(nèi)存. ?只有把QTextEdit整個(gè)delete掉, 才會(huì)釋放所有圖片資源占據(jù)的內(nèi)存. ?這是個(gè)問題, 可能需要看源碼來解決. 不過如果圖片不多的話, 這個(gè)問題也可以忽略
?
3. 如何遍歷QTextEdit中的內(nèi)容
QTextEdit中的內(nèi)容實(shí)際上是由QTextDocument維護(hù)
可以簡(jiǎn)單的理解:?QTextDocument 包含 N個(gè)QTexBlock(段落), 每個(gè)QTexBlock包含N個(gè)QTextFragment
QColor _GetRamdomColor() {QColor col; int RamdomNum = rand() % 0xffffff; char strCol[8];sprintf(strCol, "#%06x", RamdomNum); col.setNamedColor(QString::fromLocal8Bit(strCol, 8)); return col; }void MyClass::OnTest() {QTextDocument *document = ui.textEdit->document(); QTextBlock ¤tBlock = document->begin();QTextBlock::iterator it;QTextCursor cursor = ui.textEdit->textCursor(); while( true){// 在修改chatformat時(shí)會(huì)改變當(dāng)前Block的fragment// 所以++it的處理類似std::map中的erase操作for (it = currentBlock.begin(); !(it.atEnd()); ){QTextFragment currentFragment = it.fragment();QTextImageFormat newImageFormat = currentFragment.charFormat().toImageFormat();if (newImageFormat.isValid()) {// 判斷出這個(gè)fragment為image++it; continue;}if (currentFragment.isValid()){++it; int pos = currentFragment.position();QString strText = currentFragment.text();for(int i = 0; i < strText.length(); i++){ // 選擇一個(gè)字, 隨機(jī)設(shè)定顏色 QTextCharFormat fmt;fmt.setForeground(_GetRamdomColor()); QTextCursor helper = cursor;helper.setPosition(pos++);helper.setPosition(pos, QTextCursor::KeepAnchor);helper.setCharFormat(fmt);} }}currentBlock = currentBlock.next();if(!currentBlock.isValid())break;}// 光標(biāo)移動(dòng)到最后, 并設(shè)置擁有焦點(diǎn)QTextCursor c = ui.textEdit->textCursor();c.movePosition(QTextCursor::End, QTextCursor::MoveAnchor); ui.textEdit->setTextCursor(c); ui.textEdit->setFocus(Qt::MouseFocusReason); }
這段代碼用于渲染QTextEdit為炫彩, 每個(gè)字隨機(jī)分配一種顏色
遍歷的時(shí)候, 判斷是圖片還是文字. 并作相應(yīng)的處理
同時(shí), 處理下QTextDocument的contentChange事件, 即可在鍵盤輸入時(shí), 就改變字的顏色
connect(document, SIGNAL(contentsChange( int , int , int )), this, SLOT(OnContentChange( int , int , int ))); void MyClass::OnContentChange( int position, int charsRemoved, int charsAdded ) {if(charsAdded == 0)return; QTextCursor cursor = ui.textEdit->textCursor(); for (int i = 0; i < charsAdded; i++ ){int pos = position + i; // 選擇一個(gè)字, 隨機(jī)設(shè)定顏色 QTextCharFormat fmt;fmt.setForeground(_GetRamdomColor());QTextCursor helper = cursor;helper.setPosition(pos);helper.setPosition(pos+1, QTextCursor::KeepAnchor);helper.setCharFormat(fmt);}}PS: 對(duì)某段文字執(zhí)行setCharFormat也會(huì)觸發(fā)contentChange信號(hào), 并且charsRemoved == charsAdded; 可以處理一下這個(gè)case
這樣一般來說滿足了大部分需求, 做出類似QQ的聊天輸入框只需要再處理下復(fù)制黏貼圖片之類就行了. 至于Qt的rich edit中frame table list等, 需要的話, 就看看文檔吧, 感覺功能不是很必要
轉(zhuǎn)載于:https://www.cnblogs.com/lingdhox/p/3393207.html
總結(jié)
以上是生活随笔為你收集整理的QTextEdit 总结的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 浅谈osi模型 三次握手 四次挥手 dd
- 下一篇: uwsgi基础——最佳实践和问题