版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/shizheng163/article/details/53312201
因为工程中需要用到QTextEdit来显示超链接,并点击后需要打开,在网上查了好多也没有一个好的解决办法。
自己想办法解决后将思路分享给大家,我这一次也不做伸手党了。
上代码:
TextEdit * textEdit;
QList< pair<QString,bool> >strArray;
unordered_map<unsigned,int> urlIndex;
解释一下 textEdit是自己封装的输入框,继承于QTextEdit;
strArray中存储着将传入的完整字符串拆分成超链接和普通字符串后的字符串数组,true表示是超链接
urlIndex中存储了显示的文本中超链接中每一个字符对应着超链接的index.
QString CCLChatTextItemForm::GetlinkUrl(const QString &str)
{
return "<a href='"+str+"'>"+str+"</a>";
}
//#define LINK_RegulaString "((http[s]{0,1}|ftp)://[a-zA-Z0-9\\.\\-]+\\.([a-zA-Z]{2,4})(:\\d+)?(/[a-zA-Z0-9\\.\\-~!@#$%^&*+?:_/=<>]*)?)|(www.[a-zA-Z0-9\\.\\-]+\\.([a-zA-Z]{2,4})(:\\d+)?(/[a-zA-Z0-9\\.\\-~!@#$%^&*+?:_/=<>]*)?)"
//将普通网址改为html文本,显示下划线样式 蓝色
void CCLChatTextItemForm::SetTextContent(const QString &str)
{
QString content = str;
QRegExp regexp(LINK_RegulaString);
int pos = content.indexOf(regexp);
while(pos>=0){
if(pos==0){
QString tmp = content.mid(0,regexp.matchedLength());
content = content.mid(regexp.matchedLength());
strArray.push_back(make_pair(tmp,true));
}else{
QString tmp1 = content.mid(0,pos);
QString tmp2 = content.mid(pos,regexp.matchedLength());
content = content.mid(pos+regexp.matchedLength());
strArray.push_back(make_pair(tmp1,false));
strArray.push_back(make_pair(tmp2,true));
}
pos = content.indexOf(regexp);
}
if(content.size()>0)
strArray.push_back(make_pair(content,false));
for(int i=0;i<strArray.size();++i){
pair<QString,bool> t = strArray.at(i);
if(t.second == false)
this->textEdit->setUcs4String(t.first);
else{
int count = this->textEdit->toPlainText().size();
this->textEdit->append(this->GetlinkUrl(t.first));
int len = this->GetlinkUrl(t.first).size();
for(int j = count;j<count+len;++j)
urlIndex[j] = i;
}
}
}
int pos = content.indexOf(regexp);
while(pos>=0){
if(pos==0){
QString tmp = content.mid(0,regexp.matchedLength());
content = content.mid(regexp.matchedLength());
strArray.push_back(make_pair(tmp,true));
}else{
QString tmp1 = content.mid(0,pos);
QString tmp2 = content.mid(pos,regexp.matchedLength());
content = content.mid(pos+regexp.matchedLength());
strArray.push_back(make_pair(tmp1,false));
strArray.push_back(make_pair(tmp2,true));
}
pos = content.indexOf(regexp);
}
if(content.size()>0)
strArray.push_back(make_pair(content,false));
for(int i=0;i<strArray.size();++i){
pair<QString,bool> t = strArray.at(i);
if(t.second == false)
this->textEdit->setUcs4String(t.first);//这段代码自己封装的 为了解析特殊表情,相当于settext
else{
int count = this->textEdit->toPlainText().size();
this->textEdit->append(this->GetlinkUrl(t.first));
int len = this->GetlinkUrl(t.first).size();
for(int j = count;j<count+len;++j)
urlIndex[j] = i;
}
}
}
//另外在textEdit中重写鼠标释放事件
//别忘了在构造函数中和析构函数中设置鼠标跟踪属性
this->setMouseTracking(true);
void TextEdit::mouseReleaseEvent(QMouseEvent *)
{
int index = this->textCursor().anchor();//得到当前光标点击的位置在文本中的第几个
emit SignalOpenUrl(index);
}
connect(this->textEdit,SIGNAL(SignalOpenUrl(int)),this,SLOT(SlotlOpenUrl(int)));//连接
void CCLChatTextItemForm::SlotlOpenUrl(int index)
{
if(urlIndex.find(index) == this->urlIndex.end() )
return;
QString urlString = this->strArray.at(urlIndex[index]).first;
QDesktopServices::openUrl(QUrl(urlString));
}
//处理 ,至此超链接功能就写完了,总体思路是拆分字符串,确定每个超链接字符的位置,然后根据光标摁下获得的位置来取得字符串,再用QDesktopServices::openUrl(QUrl(urlString));打开