赞
踩
按照惯例,先上图
第一张图是gif动态表情,第二张图是unicode表情符号,列表控件基于QListView支持gif动态图和其他类型图片,支持指定图片显示大小与边距,Unicode表情符号是直接绘制的字符。鼠标移动上去后gif开始播放,详细请看下面的视频
基于C++,Qt的跨平台客户端,持续完善中,今日新增表情列表控件
有关数据结构体定义如下
- /// 表情列表结构
- typedef struct LNCFQCHATMASK_EMOJI_{
- uint32_t uEmojIndexIds; //索引ID
- std::u16string sMaskContents; //占位置字符
- std::u32string sEmojContents; //表情内容
- uint uEomjTypIndex; //表情类型,0默认表情,占位符表情,1字符表情,2自定义表情
- QSize sMaxEmojiSize = QSize(48,48); //表情图片最大尺寸,当超出这个尺寸的图像只会以这个尺寸显示
- }LNCFQCHATMASK_EMOJI,*PLNCFQCHATMASK_EMOJI;
QListView委托绘制的主要定义如下
- class QMovie;
- namespace LNCF_QTSOCIAL
- {
- class LNCF_QTSOCIALLIBS_API Lncf_MsgEmojiListd:public Lncf_QListDelegate
- {
- Q_OBJECT
- public:
- explicit Lncf_MsgEmojiListd(QObject *parent = nullptr);
- ~Lncf_MsgEmojiListd();
- private:
- /// 初始化表情列表委托
- /// \brief InitMsgEmojItemd
- ///
- void InitMsgEmojItemd();
- protected:
- LQTEMOJIITEMS_STYLE tEmojItemStyle; //表情图片Item风格
- QSize sItemViewsSize = QSize(40,40); //视图大小
- std::u32string sPlaceholdImgs; //默认占位图像
- QMovie *pGifMoviePlaye = nullptr; //gif播放指针
- QImage pCurrentImages; //当前帧图像
- QRect rCurrEmojiRect;
- bool bHoverInnItems = false;
- protected:
-
- /// 重写系统绘制
- virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE;
-
- /// 绘制背景
- /// \brief DrawBackgroundly
- /// \param painter
- /// \param bHover
- /// \param bSelect
- /// \param rItemRect
- /// \param index
- ///
- virtual void DrawBackgroundly(QPainter *painter,bool bHover,bool bSelect,QRectF rItemRect,const QModelIndex &index) const;
-
- /// 绘制图标
- /// \brief DrawEmojImageObj
- /// \param painter
- /// \param bHover
- /// \param rIconRect
- /// \param sContent :图标内容,unicode字符或图片路径
- /// \param uType :表情类型,0默认表情,占位符表情,1字符表情,2自定义表情
- ///
- virtual void DrawEmojImageObj(QPainter *painter,bool bHover,QRectF rImgRect,std::u32string sContent,uint uType) const;
-
- /// 绘制gif动画图像表情
- /// \brief DrawGifImgsEmoji
- /// \param painter
- /// \param bHover
- /// \param rImgRect
- /// \param sContent
- ///
- virtual void DrawGifImgsEmoji(QPainter *painter,bool bHover,QRectF rImgRect,std::u32string sContent) const;
-
- /// 绘制unicode表情符号
- /// \brief DrawUnicodeEmoji
- /// \param painter
- /// \param bHover
- /// \param rImgRect
- /// \param sContent
- ///
- virtual void DrawUnicodeEmoji(QPainter *painter,bool bHover,QRectF rImgRect,std::u32string sContent) const;
-
- /// 绘制占位图像
- /// \brief DrawPlaceholders
- /// \param painter
- /// \param bHover
- /// \param rImgRect
- ///
- virtual void DrawPlaceholders(QPainter *painter,bool bHover,QRectF rImgRect) const;
- }
- }
QListView委托绘制的主要实现如下
- namespace LNCF_QTSOCIAL
- {
- Lncf_MsgEmojiListd::Lncf_MsgEmojiListd(QObject *parent)
- : Lncf_QListDelegate(parent)
- {
- this->setParent(parent);
- this->InitMsgEmojItemd();
- }
-
- Lncf_MsgEmojiListd::~Lncf_MsgEmojiListd()
- {
- if(pGifMoviePlaye != nullptr){
- pGifMoviePlaye->stop();
- delete pGifMoviePlaye;
- }
- }
-
- /// 初始化表情列表委托
- /// \brief InitMsgEmojItemd
- ///
- void Lncf_MsgEmojiListd::InitMsgEmojItemd()
- {
- //创建QMovie以显示Gif
- if(pGifMoviePlaye == nullptr)
- pGifMoviePlaye = new QMovie();
- //绑定帧切换信号槽
- connect(pGifMoviePlaye, SIGNAL(frameChanged(int)), this, SLOT(ShowEmojAnimate(int)));
-
- sPlaceholdImgs = U":/Lncf_QtSocialRes/Res_Imagesvg/ico_emoj_placeholder.svg"; //默认占位表情符号
- SetSeleceAnimate(bSeleceAnimate);
- }
-
- /// 重写系统绘制
- void Lncf_MsgEmojiListd::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
- {
- if(index.isValid())
- {
- painter->save();
- painter->setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing|QPainter::SmoothPixmapTransform);
- painter->setPen(Qt::NoPen);
-
- //绘制图标项目
- QVariant vItemData = index.data(LQEMOJLISTITEM_ROLE::MSGEMOJLIST_ITEMS);
-
- if(!vItemData.isValid())
- return;
-
- LNCFQCHATMASK_EMOJI pViewItemData = vItemData.value<LNCFQCHATMASK_EMOJI>();
-
- //计算矩形区域
- int rWidths = option.rect.width();
- int rHeight = option.rect.height();
-
- //获取最小边长
- int nBorderWid = qMin(rWidths,rHeight);
-
- //计算偏移量
- double dLeftOffset = option.rect.left(),dTopOffset = option.rect.top();
- if(nBorderWid<rWidths)
- dLeftOffset = option.rect.left()+(rWidths-nBorderWid)/2;
-
- if(nBorderWid<rHeight)
- dTopOffset = option.rect.top()+(rHeight-nBorderWid)/2;
-
-
- //计算矩形区域
- auto rEmojiViewRect = QRectF(dLeftOffset+tEmojItemStyle.nBordersOffset,dTopOffset+tEmojItemStyle.nBordersOffset,
- nBorderWid-tEmojItemStyle.nBordersOffset*2,nBorderWid-tEmojItemStyle.nBordersOffset*2);
-
- //计算图标区域
- double dEmojWidth = rEmojiViewRect.width()/tEmojItemStyle.dEmojSpaceVals;
- double dIcoOffset = (rEmojiViewRect.width() - dEmojWidth)/2;
- auto rEmojiImgsRect = QRectF(rEmojiViewRect.left()+dIcoOffset,rEmojiViewRect.top()+dIcoOffset,dEmojWidth,dEmojWidth);
-
- bool bHoverState = option.state.testFlag(QStyle::State_MouseOver);//index.data(LQDESKOPLISTS_ROLES::DSKBTNITEMS_HOVER).toBool();//option.state.testFlag(QStyle::State_MouseOver);
-
- bool bSelectState = option.state.testFlag(QStyle::State_Selected);
-
- DrawBackgroundly(painter,bHoverState,bSelectState,rEmojiViewRect,index);
-
- DrawEmojImageObj(painter,bHoverState,rEmojiImgsRect,pViewItemData.sEmojContents,pViewItemData.uEomjTypIndex);
-
- painter->restore();
- }
- }
-
- /// 绘制背景
- /// \brief DrawBackgroundly
- /// \param painter
- /// \param bHover
- /// \param bSelect
- /// \param rItemRect
- /// \param index
- ///
- void Lncf_MsgEmojiListd::DrawBackgroundly(QPainter *painter,bool bHover,bool bSelect,QRectF rItemRect,const QModelIndex &index) const
- {
- painter->setPen(Qt::NoPen);
- painter->setBrush(Qt::NoBrush);
- if(this->bSeleceAnimate&&pItemsAnimated!=nullptr&&pItemsAnimated->pModelIndexObj == index&&!pItemsAnimated->bAnimeFinished){
- QPainterPath path;
- QRectF rect(0, 0, pItemsAnimated->qCurrentRadius, pItemsAnimated->qCurrentRadius);
- rect.moveCenter(pItemsAnimated->pAnimeStartPos);
- path.addEllipse(rect);
-
- painter->save();
- painter->setRenderHint(QPainter::Antialiasing);
- painter->setClipRect(rItemRect);
- painter->fillPath(path, this->tEmojItemStyle.cHoverBkgColor);
- painter->restore();
- }
- else{
- painter->setBrush(bHover||bSelect?tEmojItemStyle.cHoverBkgColor:tEmojItemStyle.cEmojItmBkgClr);
- painter->drawRoundedRect(rItemRect,3.0,3.0);
- }
- }
-
- /// 绘制图标
- /// \brief DrawEmojImageObj
- /// \param painter
- /// \param bHover
- /// \param rIconRect
- /// \param sContent :图标内容,unicode字符或图片路径
- /// \param uType :表情类型,0默认表情,占位符表情,1字符表情,2自定义表情
- ///
- void Lncf_MsgEmojiListd::DrawEmojImageObj(QPainter *painter,bool bHover,QRectF rImgRect,std::u32string sContent,uint uType) const
- {
- painter->setPen(Qt::NoPen);
- painter->setBrush(Qt::NoBrush);
-
- switch (uType) {
- case 0:
- case 2:{
- if(sContent.empty())
- return DrawPlaceholders(painter,bHover,rImgRect);
- //首先判断文件是否存在
- QFileInfo fImgObj(QString::fromStdU32String(sContent));
-
- if(!fImgObj.isFile()){
- printf("file Does not exist\n");
- return DrawPlaceholders(painter,bHover,rImgRect);
- }
- //判断图片文件并绘制
-
- //绘制图片
- QImage pImgObj(QString::fromStdU32String(sContent));
- if(!pImgObj.isNull())
- painter->drawImage(rImgRect,pImgObj);
- else
- return DrawPlaceholders(painter,bHover,rImgRect);
- }break;
- case 1:{
- DrawUnicodeEmoji(painter,bHover,rImgRect,sContent);
- }break;
- }
- }
-
- /// 绘制gif动画图像表情
- /// \brief DrawGifImgsEmoji
- /// \param painter
- /// \param bHover
- /// \param rImgRect
- /// \param sContent
- ///
- void Lncf_MsgEmojiListd::DrawGifImgsEmoji(QPainter *painter,bool bHover,QRectF rImgRect,std::u32string sContent) const
- {
- QImage pImgObj = bHover?pCurrentImages:QImage(QString::fromStdU32String(sContent));
- if(!pImgObj.isNull())
- painter->drawImage(rImgRect,pImgObj);
- else
- DrawPlaceholders(painter,bHover,rImgRect);
- }
-
- /// 绘制unicode表情符号
- /// \brief DrawUnicodeEmoji
- /// \param painter
- /// \param bHover
- /// \param rImgRect
- /// \param sContent
- ///
- void Lncf_MsgEmojiListd::DrawUnicodeEmoji(QPainter *painter,bool bHover,QRectF rImgRect,std::u32string sContent) const
- {
- if(!sContent.empty()){
- QFont fObj = painter->font();
- fObj.setPixelSize(sItemViewsSize.width()/1.75);
- painter->setFont(fObj);
- painter->setPen(QColor(0,0,0));
- painter->drawText(rImgRect,Qt::AlignCenter, QString::fromStdU32String(sContent));
- }
- else
- DrawPlaceholders(painter,bHover,rImgRect);
- }
-
- /// 绘制占位图像
- /// \brief DrawPlaceholders
- /// \param painter
- /// \param bHover
- /// \param bSelect
- /// \param rImgRect
- ///
- void Lncf_MsgEmojiListd::DrawPlaceholders(QPainter *painter,bool bHover,QRectF rImgRect) const
- {
- QImage pImgObj(QString::fromStdU32String(sPlaceholdImgs));
- painter->drawImage(rImgRect,pImgObj);
- }
- }
QListView派生类主要定义如下
- /// 初始化列表虚函数
- /// \brief InitMsgEmojList
- ///
- virtual void InitMsgEmojList();
- private:
- QStandardItemModel *pListItemModel = nullptr; //列表模型对象指针
- Lncf_MsgEmojiListd *pItemsDelegate = nullptr;
- public:
- /// 获取指定索引模型视图数据
- /// \brief GetItemViewsData
- /// \param index
- /// \return
- ///
- LNCFQCHATMASK_EMOJI GetItemViewsData(const QModelIndex &index) const;
-
- /// 获取所有表情项
- /// \brief GetEmojItemsList
- /// \param vList
- /// \return
- ///
- bool GetEmojItemsList(std::vector<LNCFQCHATMASK_EMOJI> &vList);
-
- /// 好友数据是否存在
- /// \brief IsExistEmojItem
- /// \param data
- /// \return
- ///
- bool IsExistEmojItem(LNCFQCHATMASK_EMOJI data);
-
- /// 更新视图项数据
- /// \brief UpdateViewItems
- /// \param index
- /// \param data :默认视图数据
- /// \param uErrMsg
- ///
- bool UpdateViewItems(const QModelIndex &index,LNCFQCHATMASK_EMOJI data,std::u16string &uErrMsg);
-
- /// 激活指定的项
- /// \brief ActiveViewsItem
- /// \param tagItem
- ///
- bool ActiveViewsItem(const LNCFQCHATMASK_EMOJI tagItem,std::u16string &uErrMsg);
- public:
- 实现QListView函数//
- void setViewMode(ViewMode mode);
-
- void setSpacing(int space);
-
- void setGridSize(const QSize &size);
- public:
- /// 添加一个表情数据
- /// \brief AddMsgEmojiItems
- /// \param data :表情数据
- ///
- void AddMsgEmojiItems(LNCFQCHATMASK_EMOJI data);
-
- /// 添加多个表情数据到列表
- /// 此操作不会删除已有数据,仅追加数据
- /// \brief AddEmojiItemList
- /// \param data
- ///
- void AddEmojiItemList(std::vector<LNCFQCHATMASK_EMOJI> &vList);
-
- /// 设置表情列表数据
- /// 注意:此操作会删除已有项
- /// \brief SetEmojiItemList
- /// \param vList
- ///
- void SetEmojiItemList(std::vector<LNCFQCHATMASK_EMOJI> &vList);
-
- /// 删除列表项
- /// \brief RemoveListItems
- /// \param tItemInf:为指定的列表项数据结构
- /// \param uErrMsg :返回错误引用参数
- /// \return
- ///
- bool RemoveListItems(LNCFQCHATMASK_EMOJI tItemInf,std::u16string &uErrMsg);
注意,在这些代码中setViewMode是重中之重,此函数将禁止将列表设置为listMode,因为如果设置为listMode则会导致不可预料的结果发生
QListView派生类主要实现代码如下
- /// 初始化列表虚函数
- /// \brief InitDesktopList
- ///
- void Lncf_MsgEmojiListv::InitMsgEmojList()
- {
- pItemsDelegate = new Lncf_MsgEmojiListd(this);
- this->setItemDelegate(pItemsDelegate);
-
- pListItemModel = new QStandardItemModel(this);
- this->setModel(pListItemModel); //在视图中安装代理
-
- connect(pItemsDelegate, &Lncf_MsgEmojiListd::EmojItemClickEvt, this, &Lncf_MsgEmojiListv::OnEmojItemsClick);
- connect(pItemsDelegate, &Lncf_MsgEmojiListd::RightclickEvents, this, &Lncf_MsgEmojiListv::OnItemRightclick);
-
- this->setEditTriggers(QAbstractItemView::SelectedClicked);
- this->setSelectionMode(SelectionMode::ExtendedSelection);
- this->setVerticalScrollMode(ScrollPerPixel);
- this->setViewMode(ViewMode::IconMode);
- this->setResizeMode(QListView::Adjust);
- this->setMovement(Movement::Snap);
- this->setGridSize(QSize(38,38));
- this->setMouseTracking(true);
- }
-
- /// 获取指定索引模型视图数据
- /// \brief GetItemViewsData
- /// \param index
- /// \return
- ///
- LNCFQCHATMASK_EMOJI Lncf_MsgEmojiListv::GetItemViewsData(const QModelIndex &index) const
- {
- if(index.isValid())
- return pListItemModel->data(index,LQEMOJLISTITEM_ROLE::MSGEMOJLIST_ITEMS).value<LNCFQCHATMASK_EMOJI>();
-
- return LNCFQCHATMASK_EMOJI();
- }
-
- /// 获取所有表情项
- /// \brief GetEmojItemsList
- /// \param vList
- /// \return
- ///
- bool Lncf_MsgEmojiListv::GetEmojItemsList(std::vector<LNCFQCHATMASK_EMOJI> &vList)
- {
- int rowCount = pListItemModel->rowCount();
- for(int i=0;i<rowCount;i++) //mIndex 是用来保存我加入项目的个数。。
- {
- QModelIndex Index = pListItemModel->index(i, 0);
- if(Index.isValid()){
- QVariant vItemData = Index.data(LQEMOJLISTITEM_ROLE::MSGEMOJLIST_ITEMS);
-
- if(vItemData.isValid()){
- LNCFQCHATMASK_EMOJI pViewItemData = vItemData.value<LNCFQCHATMASK_EMOJI>();
- vList.push_back(pViewItemData);
- }
- }
- }
- return vList.size()>0;
- }
-
- /// 好友数据是否存在
- /// \brief IsExistEmojItem
- /// \param data
- /// \return
- ///
- bool Lncf_MsgEmojiListv::IsExistEmojItem(LNCFQCHATMASK_EMOJI data)
- {
- int rowCount = pListItemModel->rowCount();
- LNCFQCHATMASK_EMOJI pViewItemData;
-
- if(data.sEmojContents.empty())
- return true;
-
- for(int i=0;i<rowCount;i++) //mIndex 是用来保存我加入项目的个数。。
- {
- QModelIndex Index = pListItemModel->index(i, 0);
- if(Index.isValid()){
- pViewItemData = pListItemModel->data(Index,LQEMOJLISTITEM_ROLE::MSGEMOJLIST_ITEMS).value<LNCFQCHATMASK_EMOJI>();
-
- if(pViewItemData.uEomjTypIndex==data.uEomjTypIndex&&pViewItemData.sMaskContents==data.sMaskContents
- &&pViewItemData.sEmojContents==data.sEmojContents)
- return true;
- }
- }
- return false;
- }
-
- /// 更新视图项数据
- /// \brief UpdateViewItems
- /// \param index
- /// \param data :默认视图数据
- /// \param uErrMsg
- ///
- bool Lncf_MsgEmojiListv::UpdateViewItems(const QModelIndex &index,LNCFQCHATMASK_EMOJI data,std::u16string &uErrMsg)
- {
- if(index.isValid()&&data.uEmojIndexIds>=0&&!data.sEmojContents.empty()){
- bool bRet = pListItemModel->setData(index,QVariant::fromValue(data),LQEMOJLISTITEM_ROLE::MSGEMOJLIST_ITEMS);
- pListItemModel->sort(0);
- if(!bRet){
- QString strErr = tr("Change Mode Index target data failed");
- uErrMsg = strErr.toStdU16String();
- }
- return bRet;
- }
- else{
- QString strErr = tr("Mode Index or data is invalid");
- uErrMsg = strErr.toStdU16String();
- }
- return false;
- }
-
- /// 激活指定的项
- /// \brief ActiveViewsItem
- /// \param tagItem
- ///
- bool Lncf_MsgEmojiListv::ActiveViewsItem(const LNCFQCHATMASK_EMOJI tagItem,std::u16string &uErrMsg)
- {
- int rowCount = pListItemModel->rowCount();
- LNCFQCHATMASK_EMOJI pItemData;
- for(int i=0;i<rowCount;i++) //mIndex 是用来保存我加入项目的个数。。
- {
- QModelIndex Index = pListItemModel->index(i, 0);
- if(Index.isValid()){
- pItemData = pListItemModel->data(Index,LQEMOJLISTITEM_ROLE::MSGEMOJLIST_ITEMS).value<LNCFQCHATMASK_EMOJI>();
- if(pItemData.uEomjTypIndex==tagItem.uEomjTypIndex&&pItemData.sEmojContents==tagItem.sEmojContents&&pItemData.sMaskContents==tagItem.sMaskContents){
- pListItemModel->sort(0);
- this->setCurrentIndex(Index);
- return true;
- }
- }
- }
- QString strErr = tr("The data for the target attribute does not exist in the list");
- uErrMsg = strErr.toStdU16String();
- return false;
- }
-
- 实现QListView函数//
- void Lncf_MsgEmojiListv::setViewMode(ViewMode mode)
- {
- if(mode == QListView::ListMode)
- mode = QListView::IconMode;
-
- this->setContentsMargins(3,3,3,3);
- this->update();
-
- QListView::setViewMode(mode);
- }
-
- void Lncf_MsgEmojiListv::setSpacing(int space)
- {
- QListView::setSpacing(space);
- }
-
- void Lncf_MsgEmojiListv::setGridSize(const QSize &size)
- {
- int nSizeWidth = qMin(size.width(),size.height());
-
- if(nSizeWidth <16)
- nSizeWidth = 16;
-
- if(nSizeWidth >256)
- nSizeWidth = 256;
-
- pItemsDelegate->SetItemViewsSize(QSize(nSizeWidth,nSizeWidth));
-
- QListView::setGridSize(QSize(nSizeWidth,nSizeWidth));
- }
-
- /// 添加一个表情数据
- /// \brief AddMsgEmojiItems
- /// \param data :表情数据
- ///
- void Lncf_MsgEmojiListv::AddMsgEmojiItems(LNCFQCHATMASK_EMOJI data)
- {
- if(IsExistEmojItem(data))
- return;
-
- QString sName = QString::fromStdU16String(data.sMaskContents);
- auto pViewItem = new QStandardItem(sName);
- pViewItem->setData(false, LQEMOJLISTITEM_ROLE::MSGEMOJLIST_ACTIV);
- pViewItem->setData(false, LQEMOJLISTITEM_ROLE::MSGEMOJLIST_CLICK);
- pViewItem->setData(false, LQEMOJLISTITEM_ROLE::MSGEMOJLIST_HOVER);
- pViewItem->setData(QVariant::fromValue(data), LQEMOJLISTITEM_ROLE::MSGEMOJLIST_ITEMS);
- pListItemModel->appendRow(pViewItem);
- }
-
- /// 添加多个表情数据到列表
- /// 此操作不会删除已有数据,仅追加数据
- /// \brief AddEmojiItemList
- /// \param data
- ///
- void Lncf_MsgEmojiListv::AddEmojiItemList(std::vector<LNCFQCHATMASK_EMOJI> &vList)
- {
- for(size_t x=0;x<vList.size();x++){
- if(!IsExistEmojItem(vList[x])){
- //printf("%s\n",QString::fromStdU16String(vList[x].sEmojContents).toStdString().c_str());
- QString sName = QString::fromStdU16String(vList[x].sMaskContents);
- auto pViewItem = new QStandardItem(sName);
- pViewItem->setData(false, LQEMOJLISTITEM_ROLE::MSGEMOJLIST_ACTIV);
- pViewItem->setData(false, LQEMOJLISTITEM_ROLE::MSGEMOJLIST_CLICK);
- pViewItem->setData(false, LQEMOJLISTITEM_ROLE::MSGEMOJLIST_HOVER);
- pViewItem->setData(QVariant::fromValue(vList[x]), LQEMOJLISTITEM_ROLE::MSGEMOJLIST_ITEMS);
- pListItemModel->appendRow(pViewItem);
- }
- }
- }
-
- /// 设置表情列表数据
- /// 注意:此操作会删除已有项
- /// \brief SetEmojiItemList
- /// \param vList
- ///
- void Lncf_MsgEmojiListv::SetEmojiItemList(std::vector<LNCFQCHATMASK_EMOJI> &vList)
- {
- pListItemModel->clear();
- AddEmojiItemList(vList);
- }
-
- /// 删除列表项
- /// \brief RemoveListItems
- /// \param tItemInf:为指定的列表项数据结构
- /// \param uErrMsg :返回错误引用参数
- /// \return
- ///
- bool Lncf_MsgEmojiListv::RemoveListItems(LNCFQCHATMASK_EMOJI tItemInf,std::u16string &uErrMsg)
- {
- int rowCount = pListItemModel->rowCount();
- LNCFQCHATMASK_EMOJI pItemData;
- for(int i=0;i<rowCount;i++) //mIndex 是用来保存我加入项目的个数。。
- {
- QModelIndex Index = pListItemModel->index(i, 0);
- pItemData = pListItemModel->data(Index,LQEMOJLISTITEM_ROLE::MSGEMOJLIST_ITEMS).value<LNCFQCHATMASK_EMOJI>();
- if(pItemData.uEomjTypIndex==tItemInf.uEomjTypIndex&&pItemData.sEmojContents==tItemInf.sEmojContents&&pItemData.sMaskContents==tItemInf.sMaskContents){
- pListItemModel->removeRow(Index.row());
- pListItemModel->sort(0);
- return true;
- }
- }
- QString strErr = tr("The target data does not exist and cannot be deleted");
- uErrMsg = strErr.toStdU16String();
- return false;
- }
至此表情列表基本就完成了,根据上面的代码您可以复刻一个表情列表控件,自己在完成属性接口与信号连接即可使用
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。