[Qt] 可显示表情的编辑器
似乎很久没发过新贴了。在 libfetion-gui 项目里有这样一个任务:信息编辑框表情图片显示。目前的显示方式是直接显示代码,如 :) , :-p 等
实现如下:
fxeditor.h
#ifndef FXEDITOR_H
#define FXEDITOR_H
#include <QTextEdit>
typedef QPair<QString,QString> mypair;
class FxEditor : public QTextEdit
{
Q_OBJECT
public:
FxEditor(QWidget*parent = 0);
QString toPlainText () const;
public slots:
void onTextChanged();
private:
// do not use map
// because it sort the key by char order
QMap<QString,QString> strToHtml;
QList<mypair> strToHtmlList;
};
#endif // FXEDITOR_H
fxeditor.cpp
#include "fxeditor.h"
#include <QDebug>
FxEditor::FxEditor(QWidget*parent):QTextEdit(parent)
{
// setup the list
// this list should not be a class alone or a global variable?
mypair a("o:)","<img src=\"./faces/47.gif\" />");
mypair b(":)","<img src=\"./faces/1.gif\" />");
strToHtmlList<<a<<b;
strToHtml[">:)"]="<img src=\"%path%/50.gif\" />";
strToHtml["o:)"]="<img src=\"%path%/47.gif\" />"; // error :)
strToHtml["*-:)"]="<img src=\"%path%/37.gif\" />";
strToHtml[":-d"]="<img src=\"%path%/2.gif\" />";
strToHtml[":-o"]="<img src=\"%path%/4.gif\" />";
strToHtml[":-p"]="<img src=\"%path%/5.gif\" />";
strToHtml["(h)"]="<img src=\"%path%/6.gif\" />";
strToHtml[":-@"]="<img src=\"%path%/7.gif\" />";
strToHtml[":("]="<img src=\"%path%/8.gif\" />";
strToHtml[":'("]="<img src=\"%path%/9.gif\" />";
strToHtml[":\">"]="<img src=\"%path%/10.gif\" />"; // work delay
strToHtml["^o)"]="<img src=\"%path%/11.gif\" />";
strToHtml[":&"]="<img src=\"%path%/12.gif\" />";// work delay
strToHtml["8o|"]="<img src=\"%path%/13.gif\" />";
strToHtml["|-)"]="<img src=\"%path%/14.gif\" />";
strToHtml[":-#"]="<img src=\"%path%/15.gif\" />";
strToHtml["8-)"]="<img src=\"%path%/16.gif\" />";
strToHtml["(s)"]="<img src=\"%path%/17.gif\" />";
strToHtml["(st)"]="<img src=\"%path%/18.gif\" />";
strToHtml["(o)"]="<img src=\"%path%/19.gif\" />";
strToHtml["(l)"]="<img src=\"%path%/20.gif\" />";
strToHtml["(u)"]="<img src=\"%path%/21.gif\" />";
strToHtml["(@)"]="<img src=\"%path%/22.gif\" />";
strToHtml["(&)"]="<img src=\"%path%/23.gif\" />";// work delay
strToHtml["(sn)"]="<img src=\"%path%/24.gif\" />";
strToHtml["(*)"]="<img src=\"%path%/25.gif\" />";
strToHtml["(#)"]="<img src=\"%path%/26.gif\" />";
strToHtml["(r)"]="<img src=\"%path%/27.gif\" />";
strToHtml["(})"]="<img src=\"%path%/28.gif\" />";
strToHtml["({)"]="<img src=\"%path%/29.gif\" />";
strToHtml["(k)"]="<img src=\"%path%/30.gif\" />";
strToHtml["(f)"]="<img src=\"%path%/31.gif\" />";
strToHtml["(w)"]="<img src=\"%path%/32.gif\" />";
strToHtml["(g)"]="<img src=\"%path%/33.gif\" />";
strToHtml["(^)"]="<img src=\"%path%/34.gif\" />";
strToHtml["-8"]="<img src=\"%path%/35.gif\" />";
strToHtml["(i)"]="<img src=\"%path%/36.gif\" />";
strToHtml["(c)"]="<img src=\"%path%/38.gif\" />";
strToHtml["(um)"]="<img src=\"%path%/39.gif\" />";
strToHtml["(mp)"]="<img src=\"%path%/40.gif\" />";
strToHtml["(co)"]="<img src=\"%path%/41.gif\" />";
strToHtml[":-|"]="<img src=\"%path%/42.gif\" />";
strToHtml[":-/"]="<img src=\"%path%/43.gif\" />";
strToHtml[":-s"]="<img src=\"%path%/44.gif\" />";
strToHtml[")-|"]="<img src=\"%path%/45.gif\" />";
strToHtml["(d)"]="<img src=\"%path%/46.gif\" />";
strToHtml[":-?"]="<img src=\"%path%/48.gif\" />";
strToHtml["(y)"]="<img src=\"%path%/49.gif\" />";
strToHtml[":-b"]="<img src=\"%path%/51.gif\" />";
strToHtml["b)"]="<img src=\"%path%/52.gif\" />";
strToHtml[";)"]="<img src=\"%path%/3.gif\" />";
strToHtml[":)"]="<img src=\"%path%/1.gif\" />";
//strToHtml[""]="<img src=\"%path%/.gif\" />";
connect(this,SIGNAL(textChanged()),this,SLOT(onTextChanged()));
}
QString FxEditor::toPlainText()const
{
QString oristr = toHtml();
//qDebug()<<oristr;
// replace all <img ..> to str
QMap<QString, QString>::const_iterator i = strToHtml.constBegin();
while (i != strToHtml.end()) {
QString k = i.value();
oristr.replace(k.replace("%path%","./faces"),i.key());
++i;
}
// replace all html tags
// remove <!Do..
oristr.remove(QRegExp("<!(^>)+>"));
// remove stylesheet tag and its content
oristr.remove(QRegExp("<[^>]+css\">[^<]*</style>"));
// remove other tags
oristr.remove(QRegExp("<[^>]+>"));
oristr.replace("<","<");
oristr.replace(">",">");
// remove the newline
oristr.remove(0,2);
//qDebug()<<"\n orient plainText return :"<<QTextEdit::toPlainText()<<"\n";
//return QTextEdit::toPlainText();
return oristr;
}
void FxEditor::onTextChanged()
{
static bool changeByMe = false;
if(changeByMe)
return;
QString oristr = toHtml();
QTextDocument *td = this->document();
bool changed = false;
int newCursorPosition = this->textCursor().position();
QMap<QString,QString>::const_iterator i = strToHtml.constBegin();
qDebug()<<oristr;
//qDebug()<<QString("position:%1").arg(newCursorPosition);
while (i != strToHtml.end()) {
//计算新位置
QTextCursor foundCursor(td);
while(!foundCursor.isNull() && !foundCursor.atEnd()){
foundCursor = td->find(i.key(),foundCursor);
if(!foundCursor.isNull()){
qDebug()<<i.key();
changed=true;
int foundCursorPosition= foundCursor.position();
if(foundCursorPosition >= newCursorPosition){
//@ TO FIX
//when & turn to & && > turn to >
//this doen't work as expect.
newCursorPosition -= i.key().size()-1;
}
//QString str = td->toHtml();
//str.replace(foundCursorPosition,i.key().size(), i.value());
}
}
//切换
QString k = i.value();
oristr.replace(i.key(),k.replace("%path%","./faces"));
++i;
}
//qDebug()<<QString("position:%1").arg(newCursorPosition);
if(changed){
changeByMe = true;
setHtml(oristr);
QTextCursor c(td);
c.setPosition(newCursorPosition);
this->setTextCursor(c);
changeByMe = false;
}
qDebug()<<"\n"<<toPlainText()<<"\n";
}
表情符对应的图片是硬编码的,这个做法扩展性不好,更好的做法是从外部读取字符和图片对应表。这样就可以方便的支持自定义表情了
页:
[1]