qtextedit固定内容_QTextEdit 总结

该文档有人翻译了一下(本来我想翻译- -!), 参考Rich Text Processing富文本处理

QTextEdit的组成比较复杂, 最好看看文档了解一下Rich Text Document Structure

1. HTML形式操纵Qtextedit

QTextEdit支持HTML的一个子集, 所以对于简单的使用, 可以直接插入HTML代码

editor->append("");

通过插入html代码, 可以实现图片, 字体, 字号, 颜色等功能

ps: QTextEdit中img标签仅支持src, width, height三个属性, 使用其他属性会自动被Qt过滤掉, 即editor->toHtml()中无法找到

可以通过正则来过滤toHtml()生成的代码

2. 在QTextEdit中播放gif

QTextEdit虽然直接img标签, 但默认不播放gif, 也不会显示gif的第一帧 (如果你不需要编辑功能的话, 其实可以用QWebView来查看)

所以在QTextEdit中播放gif需要手动换帧.

QMovie内置了gif解析和定时器功能.

QTextDocument 使用addResource 把图片资源加载进来, 然后通过QMovie->start启动定时器, 不断更新图片资源

QString g_fileName = ":/test.gif";

QUrl g_url("TestImageTag");

voidMyClass::InsertImage()

{

QMovie* movie = new QMovie(this);

movie->setFileName(g_fileName);

movie->setCacheMode(QMovie::CacheNone);//换帧时刷新

connect(movie, SIGNAL(frameChanged(int)), this, SLOT(OnAnimate(int)));

movie->start();

}

g_url 是自定义的标签, 用来标记QTextDocument 中的resource

void MyClass::OnAnimate(inta)

{if (QMovie* movie = qobject_cast(sender()))

{

document()->addResource(QTextDocument::ImageResource, //替换图片为当前帧

g_url, movie->currentPixmap());

setLineWrapColumnOrWidth(lineWrapColumnOrWidth());//刷新显示

}

}

addResource 指定ImageResource, 然后根据url, 若url已存在, 则更新资源, 若url不存在, 则添加资源

这样就实现刷新gif的帧. 这样, QTextEdit就会显示gif动画了

最后是添加gif图片:

可以插入HTML:

editor->append("");

即img中指定为我们自定义的url即可

也可以使用QTextCursor插入:

QTextCursor cursor = editor->textCursor();

QTextImageFormat imageFormat;

imageFormat.setName("TestImageTag");

cursor.insertImage(imageFormat);

PS: 可以使用两个数组来保存自定义的URL和QMOVIE, 以便管理资源释放等问题

PS2: 在我的测试中, 即使调用了Qtextedit和QTextDocument的clear也无法释放addResource图片资源的内存.  只有把QTextEdit整个delete掉, 才会释放所有图片资源占据的内存.  这是个问题, 可能需要看源码来解决. 不过如果图片不多的话, 这个问题也可以忽略

3. 如何遍历QTextEdit中的内容

QTextEdit中的内容实际上是由QTextDocument维护

可以简单的理解: QTextDocument 包含 N个QTexBlock(段落), 每个QTexBlock包含N个QTextFragment

QColor _GetRamdomColor()

{

QColor col;int RamdomNum = rand() % 0xffffff;char strCol[8];

sprintf(strCol,"#%06x", RamdomNum);

col.setNamedColor(QString::fromLocal8Bit(strCol,8));returncol;

}voidMyClass::OnTest()

{

QTextDocument*document = ui.textEdit->document();

QTextBlock&currentBlock = document->begin();

QTextBlock::iterator it;

QTextCursor cursor= ui.textEdit->textCursor();while( true)

{//在修改chatformat时会改变当前Block的fragment//所以++it的处理类似std::map中的erase操作

for (it = currentBlock.begin(); !(it.atEnd()); )

{

QTextFragment currentFragment=it.fragment();

QTextImageFormat newImageFormat=currentFragment.charFormat().toImageFormat();if(newImageFormat.isValid()) {//判断出这个fragment为image

++it;continue;

}if(currentFragment.isValid())

{++it;int pos =currentFragment.position();

QString strText=currentFragment.text();for(int i = 0; i < strText.length(); i++)

{//选择一个字, 随机设定颜色

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;

}//光标移动到最后, 并设置拥有焦点

QTextCursor c = ui.textEdit->textCursor();

c.movePosition(QTextCursor::End, QTextCursor::MoveAnchor);

ui.textEdit->setTextCursor(c);

ui.textEdit->setFocus(Qt::MouseFocusReason);

}

这段代码用于渲染QTextEdit为炫彩, 每个字随机分配一种颜色

遍历的时候, 判断是图片还是文字. 并作相应的处理

同时, 处理下QTextDocument的contentChange事件, 即可在键盘输入时, 就改变字的颜色

connect(document, SIGNAL(contentsChange( int , int , int)),this, SLOT(OnContentChange( int , int , int )));

void MyClass::OnContentChange( int position, int charsRemoved, intcharsAdded )

{if(charsAdded == 0)return;QTextCursor cursor= ui.textEdit->textCursor();for (int i = 0; i < charsAdded; i++)

{int pos = position +i;//选择一个字, 随机设定颜色

QTextCharFormat fmt;

fmt.setForeground(_GetRamdomColor());

QTextCursor helper=cursor;

helper.setPosition(pos);

helper.setPosition(pos+1, QTextCursor::KeepAnchor);

helper.setCharFormat(fmt);

}

}

PS: 对某段文字执行setCharFormat也会触发contentChange信号, 并且charsRemoved == charsAdded; 可以处理一下这个case这样一般来说满足了大部分需求, 做出类似QQ的聊天输入框只需要再处理下复制黏贴图片之类就行了.至于Qt的rich edit中frame table list等, 需要的话, 就看看文档吧, 感觉功能不是很必要

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值