当前位置:   article > 正文

C++,Qt,QListView 开发表情列表控件_qtemoji表情c++库

qtemoji表情c++库

按照惯例,先上图

第一张图是gif动态表情,第二张图是unicode表情符号,列表控件基于QListView支持gif动态图和其他类型图片,支持指定图片显示大小与边距,Unicode表情符号是直接绘制的字符。鼠标移动上去后gif开始播放,详细请看下面的视频 

基于C++,Qt的跨平台客户端,持续完善中,今日新增表情列表控件

有关数据结构体定义如下

  1. /// 表情列表结构
  2. typedef struct LNCFQCHATMASK_EMOJI_{
  3. uint32_t uEmojIndexIds; //索引ID
  4. std::u16string sMaskContents; //占位置字符
  5. std::u32string sEmojContents; //表情内容
  6. uint uEomjTypIndex; //表情类型,0默认表情,占位符表情,1字符表情,2自定义表情
  7. QSize sMaxEmojiSize = QSize(48,48); //表情图片最大尺寸,当超出这个尺寸的图像只会以这个尺寸显示
  8. }LNCFQCHATMASK_EMOJI,*PLNCFQCHATMASK_EMOJI;

QListView委托绘制的主要定义如下

  1. class QMovie;
  2. namespace LNCF_QTSOCIAL
  3. {
  4. class LNCF_QTSOCIALLIBS_API Lncf_MsgEmojiListd:public Lncf_QListDelegate
  5. {
  6. Q_OBJECT
  7. public:
  8. explicit Lncf_MsgEmojiListd(QObject *parent = nullptr);
  9. ~Lncf_MsgEmojiListd();
  10. private:
  11. /// 初始化表情列表委托
  12. /// \brief InitMsgEmojItemd
  13. ///
  14. void InitMsgEmojItemd();
  15. protected:
  16. LQTEMOJIITEMS_STYLE tEmojItemStyle; //表情图片Item风格
  17. QSize sItemViewsSize = QSize(40,40); //视图大小
  18. std::u32string sPlaceholdImgs; //默认占位图像
  19. QMovie *pGifMoviePlaye = nullptr; //gif播放指针
  20. QImage pCurrentImages; //当前帧图像
  21. QRect rCurrEmojiRect;
  22. bool bHoverInnItems = false;
  23. protected:
  24. /// 重写系统绘制
  25. virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE;
  26. /// 绘制背景
  27. /// \brief DrawBackgroundly
  28. /// \param painter
  29. /// \param bHover
  30. /// \param bSelect
  31. /// \param rItemRect
  32. /// \param index
  33. ///
  34. virtual void DrawBackgroundly(QPainter *painter,bool bHover,bool bSelect,QRectF rItemRect,const QModelIndex &index) const;
  35. /// 绘制图标
  36. /// \brief DrawEmojImageObj
  37. /// \param painter
  38. /// \param bHover
  39. /// \param rIconRect
  40. /// \param sContent :图标内容,unicode字符或图片路径
  41. /// \param uType :表情类型,0默认表情,占位符表情,1字符表情,2自定义表情
  42. ///
  43. virtual void DrawEmojImageObj(QPainter *painter,bool bHover,QRectF rImgRect,std::u32string sContent,uint uType) const;
  44. /// 绘制gif动画图像表情
  45. /// \brief DrawGifImgsEmoji
  46. /// \param painter
  47. /// \param bHover
  48. /// \param rImgRect
  49. /// \param sContent
  50. ///
  51. virtual void DrawGifImgsEmoji(QPainter *painter,bool bHover,QRectF rImgRect,std::u32string sContent) const;
  52. /// 绘制unicode表情符号
  53. /// \brief DrawUnicodeEmoji
  54. /// \param painter
  55. /// \param bHover
  56. /// \param rImgRect
  57. /// \param sContent
  58. ///
  59. virtual void DrawUnicodeEmoji(QPainter *painter,bool bHover,QRectF rImgRect,std::u32string sContent) const;
  60. /// 绘制占位图像
  61. /// \brief DrawPlaceholders
  62. /// \param painter
  63. /// \param bHover
  64. /// \param rImgRect
  65. ///
  66. virtual void DrawPlaceholders(QPainter *painter,bool bHover,QRectF rImgRect) const;
  67. }
  68. }

 QListView委托绘制的主要实现如下

  1. namespace LNCF_QTSOCIAL
  2. {
  3. Lncf_MsgEmojiListd::Lncf_MsgEmojiListd(QObject *parent)
  4. : Lncf_QListDelegate(parent)
  5. {
  6. this->setParent(parent);
  7. this->InitMsgEmojItemd();
  8. }
  9. Lncf_MsgEmojiListd::~Lncf_MsgEmojiListd()
  10. {
  11. if(pGifMoviePlaye != nullptr){
  12. pGifMoviePlaye->stop();
  13. delete pGifMoviePlaye;
  14. }
  15. }
  16. /// 初始化表情列表委托
  17. /// \brief InitMsgEmojItemd
  18. ///
  19. void Lncf_MsgEmojiListd::InitMsgEmojItemd()
  20. {
  21. //创建QMovie以显示Gif
  22. if(pGifMoviePlaye == nullptr)
  23. pGifMoviePlaye = new QMovie();
  24. //绑定帧切换信号槽
  25. connect(pGifMoviePlaye, SIGNAL(frameChanged(int)), this, SLOT(ShowEmojAnimate(int)));
  26. sPlaceholdImgs = U":/Lncf_QtSocialRes/Res_Imagesvg/ico_emoj_placeholder.svg"; //默认占位表情符号
  27. SetSeleceAnimate(bSeleceAnimate);
  28. }
  29. /// 重写系统绘制
  30. void Lncf_MsgEmojiListd::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
  31. {
  32. if(index.isValid())
  33. {
  34. painter->save();
  35. painter->setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing|QPainter::SmoothPixmapTransform);
  36. painter->setPen(Qt::NoPen);
  37. //绘制图标项目
  38. QVariant vItemData = index.data(LQEMOJLISTITEM_ROLE::MSGEMOJLIST_ITEMS);
  39. if(!vItemData.isValid())
  40. return;
  41. LNCFQCHATMASK_EMOJI pViewItemData = vItemData.value<LNCFQCHATMASK_EMOJI>();
  42. //计算矩形区域
  43. int rWidths = option.rect.width();
  44. int rHeight = option.rect.height();
  45. //获取最小边长
  46. int nBorderWid = qMin(rWidths,rHeight);
  47. //计算偏移量
  48. double dLeftOffset = option.rect.left(),dTopOffset = option.rect.top();
  49. if(nBorderWid<rWidths)
  50. dLeftOffset = option.rect.left()+(rWidths-nBorderWid)/2;
  51. if(nBorderWid<rHeight)
  52. dTopOffset = option.rect.top()+(rHeight-nBorderWid)/2;
  53. //计算矩形区域
  54. auto rEmojiViewRect = QRectF(dLeftOffset+tEmojItemStyle.nBordersOffset,dTopOffset+tEmojItemStyle.nBordersOffset,
  55. nBorderWid-tEmojItemStyle.nBordersOffset*2,nBorderWid-tEmojItemStyle.nBordersOffset*2);
  56. //计算图标区域
  57. double dEmojWidth = rEmojiViewRect.width()/tEmojItemStyle.dEmojSpaceVals;
  58. double dIcoOffset = (rEmojiViewRect.width() - dEmojWidth)/2;
  59. auto rEmojiImgsRect = QRectF(rEmojiViewRect.left()+dIcoOffset,rEmojiViewRect.top()+dIcoOffset,dEmojWidth,dEmojWidth);
  60. bool bHoverState = option.state.testFlag(QStyle::State_MouseOver);//index.data(LQDESKOPLISTS_ROLES::DSKBTNITEMS_HOVER).toBool();//option.state.testFlag(QStyle::State_MouseOver);
  61. bool bSelectState = option.state.testFlag(QStyle::State_Selected);
  62. DrawBackgroundly(painter,bHoverState,bSelectState,rEmojiViewRect,index);
  63. DrawEmojImageObj(painter,bHoverState,rEmojiImgsRect,pViewItemData.sEmojContents,pViewItemData.uEomjTypIndex);
  64. painter->restore();
  65. }
  66. }
  67. /// 绘制背景
  68. /// \brief DrawBackgroundly
  69. /// \param painter
  70. /// \param bHover
  71. /// \param bSelect
  72. /// \param rItemRect
  73. /// \param index
  74. ///
  75. void Lncf_MsgEmojiListd::DrawBackgroundly(QPainter *painter,bool bHover,bool bSelect,QRectF rItemRect,const QModelIndex &index) const
  76. {
  77. painter->setPen(Qt::NoPen);
  78. painter->setBrush(Qt::NoBrush);
  79. if(this->bSeleceAnimate&&pItemsAnimated!=nullptr&&pItemsAnimated->pModelIndexObj == index&&!pItemsAnimated->bAnimeFinished){
  80. QPainterPath path;
  81. QRectF rect(0, 0, pItemsAnimated->qCurrentRadius, pItemsAnimated->qCurrentRadius);
  82. rect.moveCenter(pItemsAnimated->pAnimeStartPos);
  83. path.addEllipse(rect);
  84. painter->save();
  85. painter->setRenderHint(QPainter::Antialiasing);
  86. painter->setClipRect(rItemRect);
  87. painter->fillPath(path, this->tEmojItemStyle.cHoverBkgColor);
  88. painter->restore();
  89. }
  90. else{
  91. painter->setBrush(bHover||bSelect?tEmojItemStyle.cHoverBkgColor:tEmojItemStyle.cEmojItmBkgClr);
  92. painter->drawRoundedRect(rItemRect,3.0,3.0);
  93. }
  94. }
  95. /// 绘制图标
  96. /// \brief DrawEmojImageObj
  97. /// \param painter
  98. /// \param bHover
  99. /// \param rIconRect
  100. /// \param sContent :图标内容,unicode字符或图片路径
  101. /// \param uType :表情类型,0默认表情,占位符表情,1字符表情,2自定义表情
  102. ///
  103. void Lncf_MsgEmojiListd::DrawEmojImageObj(QPainter *painter,bool bHover,QRectF rImgRect,std::u32string sContent,uint uType) const
  104. {
  105. painter->setPen(Qt::NoPen);
  106. painter->setBrush(Qt::NoBrush);
  107. switch (uType) {
  108. case 0:
  109. case 2:{
  110. if(sContent.empty())
  111. return DrawPlaceholders(painter,bHover,rImgRect);
  112. //首先判断文件是否存在
  113. QFileInfo fImgObj(QString::fromStdU32String(sContent));
  114. if(!fImgObj.isFile()){
  115. printf("file Does not exist\n");
  116. return DrawPlaceholders(painter,bHover,rImgRect);
  117. }
  118. //判断图片文件并绘制
  119. //绘制图片
  120. QImage pImgObj(QString::fromStdU32String(sContent));
  121. if(!pImgObj.isNull())
  122. painter->drawImage(rImgRect,pImgObj);
  123. else
  124. return DrawPlaceholders(painter,bHover,rImgRect);
  125. }break;
  126. case 1:{
  127. DrawUnicodeEmoji(painter,bHover,rImgRect,sContent);
  128. }break;
  129. }
  130. }
  131. /// 绘制gif动画图像表情
  132. /// \brief DrawGifImgsEmoji
  133. /// \param painter
  134. /// \param bHover
  135. /// \param rImgRect
  136. /// \param sContent
  137. ///
  138. void Lncf_MsgEmojiListd::DrawGifImgsEmoji(QPainter *painter,bool bHover,QRectF rImgRect,std::u32string sContent) const
  139. {
  140. QImage pImgObj = bHover?pCurrentImages:QImage(QString::fromStdU32String(sContent));
  141. if(!pImgObj.isNull())
  142. painter->drawImage(rImgRect,pImgObj);
  143. else
  144. DrawPlaceholders(painter,bHover,rImgRect);
  145. }
  146. /// 绘制unicode表情符号
  147. /// \brief DrawUnicodeEmoji
  148. /// \param painter
  149. /// \param bHover
  150. /// \param rImgRect
  151. /// \param sContent
  152. ///
  153. void Lncf_MsgEmojiListd::DrawUnicodeEmoji(QPainter *painter,bool bHover,QRectF rImgRect,std::u32string sContent) const
  154. {
  155. if(!sContent.empty()){
  156. QFont fObj = painter->font();
  157. fObj.setPixelSize(sItemViewsSize.width()/1.75);
  158. painter->setFont(fObj);
  159. painter->setPen(QColor(0,0,0));
  160. painter->drawText(rImgRect,Qt::AlignCenter, QString::fromStdU32String(sContent));
  161. }
  162. else
  163. DrawPlaceholders(painter,bHover,rImgRect);
  164. }
  165. /// 绘制占位图像
  166. /// \brief DrawPlaceholders
  167. /// \param painter
  168. /// \param bHover
  169. /// \param bSelect
  170. /// \param rImgRect
  171. ///
  172. void Lncf_MsgEmojiListd::DrawPlaceholders(QPainter *painter,bool bHover,QRectF rImgRect) const
  173. {
  174. QImage pImgObj(QString::fromStdU32String(sPlaceholdImgs));
  175. painter->drawImage(rImgRect,pImgObj);
  176. }
  177. }

QListView派生类主要定义如下

  1. /// 初始化列表虚函数
  2. /// \brief InitMsgEmojList
  3. ///
  4. virtual void InitMsgEmojList();
  5. private:
  6. QStandardItemModel *pListItemModel = nullptr; //列表模型对象指针
  7. Lncf_MsgEmojiListd *pItemsDelegate = nullptr;
  8. public:
  9. /// 获取指定索引模型视图数据
  10. /// \brief GetItemViewsData
  11. /// \param index
  12. /// \return
  13. ///
  14. LNCFQCHATMASK_EMOJI GetItemViewsData(const QModelIndex &index) const;
  15. /// 获取所有表情项
  16. /// \brief GetEmojItemsList
  17. /// \param vList
  18. /// \return
  19. ///
  20. bool GetEmojItemsList(std::vector<LNCFQCHATMASK_EMOJI> &vList);
  21. /// 好友数据是否存在
  22. /// \brief IsExistEmojItem
  23. /// \param data
  24. /// \return
  25. ///
  26. bool IsExistEmojItem(LNCFQCHATMASK_EMOJI data);
  27. /// 更新视图项数据
  28. /// \brief UpdateViewItems
  29. /// \param index
  30. /// \param data :默认视图数据
  31. /// \param uErrMsg
  32. ///
  33. bool UpdateViewItems(const QModelIndex &index,LNCFQCHATMASK_EMOJI data,std::u16string &uErrMsg);
  34. /// 激活指定的项
  35. /// \brief ActiveViewsItem
  36. /// \param tagItem
  37. ///
  38. bool ActiveViewsItem(const LNCFQCHATMASK_EMOJI tagItem,std::u16string &uErrMsg);
  39. public:
  40. 实现QListView函数//
  41. void setViewMode(ViewMode mode);
  42. void setSpacing(int space);
  43. void setGridSize(const QSize &size);
  44. public:
  45. /// 添加一个表情数据
  46. /// \brief AddMsgEmojiItems
  47. /// \param data :表情数据
  48. ///
  49. void AddMsgEmojiItems(LNCFQCHATMASK_EMOJI data);
  50. /// 添加多个表情数据到列表
  51. /// 此操作不会删除已有数据,仅追加数据
  52. /// \brief AddEmojiItemList
  53. /// \param data
  54. ///
  55. void AddEmojiItemList(std::vector<LNCFQCHATMASK_EMOJI> &vList);
  56. /// 设置表情列表数据
  57. /// 注意:此操作会删除已有项
  58. /// \brief SetEmojiItemList
  59. /// \param vList
  60. ///
  61. void SetEmojiItemList(std::vector<LNCFQCHATMASK_EMOJI> &vList);
  62. /// 删除列表项
  63. /// \brief RemoveListItems
  64. /// \param tItemInf:为指定的列表项数据结构
  65. /// \param uErrMsg :返回错误引用参数
  66. /// \return
  67. ///
  68. bool RemoveListItems(LNCFQCHATMASK_EMOJI tItemInf,std::u16string &uErrMsg);

 注意,在这些代码中setViewMode是重中之重,此函数将禁止将列表设置为listMode,因为如果设置为listMode则会导致不可预料的结果发生

QListView派生类主要实现代码如下

  1. /// 初始化列表虚函数
  2. /// \brief InitDesktopList
  3. ///
  4. void Lncf_MsgEmojiListv::InitMsgEmojList()
  5. {
  6. pItemsDelegate = new Lncf_MsgEmojiListd(this);
  7. this->setItemDelegate(pItemsDelegate);
  8. pListItemModel = new QStandardItemModel(this);
  9. this->setModel(pListItemModel); //在视图中安装代理
  10. connect(pItemsDelegate, &Lncf_MsgEmojiListd::EmojItemClickEvt, this, &Lncf_MsgEmojiListv::OnEmojItemsClick);
  11. connect(pItemsDelegate, &Lncf_MsgEmojiListd::RightclickEvents, this, &Lncf_MsgEmojiListv::OnItemRightclick);
  12. this->setEditTriggers(QAbstractItemView::SelectedClicked);
  13. this->setSelectionMode(SelectionMode::ExtendedSelection);
  14. this->setVerticalScrollMode(ScrollPerPixel);
  15. this->setViewMode(ViewMode::IconMode);
  16. this->setResizeMode(QListView::Adjust);
  17. this->setMovement(Movement::Snap);
  18. this->setGridSize(QSize(38,38));
  19. this->setMouseTracking(true);
  20. }
  21. /// 获取指定索引模型视图数据
  22. /// \brief GetItemViewsData
  23. /// \param index
  24. /// \return
  25. ///
  26. LNCFQCHATMASK_EMOJI Lncf_MsgEmojiListv::GetItemViewsData(const QModelIndex &index) const
  27. {
  28. if(index.isValid())
  29. return pListItemModel->data(index,LQEMOJLISTITEM_ROLE::MSGEMOJLIST_ITEMS).value<LNCFQCHATMASK_EMOJI>();
  30. return LNCFQCHATMASK_EMOJI();
  31. }
  32. /// 获取所有表情项
  33. /// \brief GetEmojItemsList
  34. /// \param vList
  35. /// \return
  36. ///
  37. bool Lncf_MsgEmojiListv::GetEmojItemsList(std::vector<LNCFQCHATMASK_EMOJI> &vList)
  38. {
  39. int rowCount = pListItemModel->rowCount();
  40. for(int i=0;i<rowCount;i++) //mIndex 是用来保存我加入项目的个数。。
  41. {
  42. QModelIndex Index = pListItemModel->index(i, 0);
  43. if(Index.isValid()){
  44. QVariant vItemData = Index.data(LQEMOJLISTITEM_ROLE::MSGEMOJLIST_ITEMS);
  45. if(vItemData.isValid()){
  46. LNCFQCHATMASK_EMOJI pViewItemData = vItemData.value<LNCFQCHATMASK_EMOJI>();
  47. vList.push_back(pViewItemData);
  48. }
  49. }
  50. }
  51. return vList.size()>0;
  52. }
  53. /// 好友数据是否存在
  54. /// \brief IsExistEmojItem
  55. /// \param data
  56. /// \return
  57. ///
  58. bool Lncf_MsgEmojiListv::IsExistEmojItem(LNCFQCHATMASK_EMOJI data)
  59. {
  60. int rowCount = pListItemModel->rowCount();
  61. LNCFQCHATMASK_EMOJI pViewItemData;
  62. if(data.sEmojContents.empty())
  63. return true;
  64. for(int i=0;i<rowCount;i++) //mIndex 是用来保存我加入项目的个数。。
  65. {
  66. QModelIndex Index = pListItemModel->index(i, 0);
  67. if(Index.isValid()){
  68. pViewItemData = pListItemModel->data(Index,LQEMOJLISTITEM_ROLE::MSGEMOJLIST_ITEMS).value<LNCFQCHATMASK_EMOJI>();
  69. if(pViewItemData.uEomjTypIndex==data.uEomjTypIndex&&pViewItemData.sMaskContents==data.sMaskContents
  70. &&pViewItemData.sEmojContents==data.sEmojContents)
  71. return true;
  72. }
  73. }
  74. return false;
  75. }
  76. /// 更新视图项数据
  77. /// \brief UpdateViewItems
  78. /// \param index
  79. /// \param data :默认视图数据
  80. /// \param uErrMsg
  81. ///
  82. bool Lncf_MsgEmojiListv::UpdateViewItems(const QModelIndex &index,LNCFQCHATMASK_EMOJI data,std::u16string &uErrMsg)
  83. {
  84. if(index.isValid()&&data.uEmojIndexIds>=0&&!data.sEmojContents.empty()){
  85. bool bRet = pListItemModel->setData(index,QVariant::fromValue(data),LQEMOJLISTITEM_ROLE::MSGEMOJLIST_ITEMS);
  86. pListItemModel->sort(0);
  87. if(!bRet){
  88. QString strErr = tr("Change Mode Index target data failed");
  89. uErrMsg = strErr.toStdU16String();
  90. }
  91. return bRet;
  92. }
  93. else{
  94. QString strErr = tr("Mode Index or data is invalid");
  95. uErrMsg = strErr.toStdU16String();
  96. }
  97. return false;
  98. }
  99. /// 激活指定的项
  100. /// \brief ActiveViewsItem
  101. /// \param tagItem
  102. ///
  103. bool Lncf_MsgEmojiListv::ActiveViewsItem(const LNCFQCHATMASK_EMOJI tagItem,std::u16string &uErrMsg)
  104. {
  105. int rowCount = pListItemModel->rowCount();
  106. LNCFQCHATMASK_EMOJI pItemData;
  107. for(int i=0;i<rowCount;i++) //mIndex 是用来保存我加入项目的个数。。
  108. {
  109. QModelIndex Index = pListItemModel->index(i, 0);
  110. if(Index.isValid()){
  111. pItemData = pListItemModel->data(Index,LQEMOJLISTITEM_ROLE::MSGEMOJLIST_ITEMS).value<LNCFQCHATMASK_EMOJI>();
  112. if(pItemData.uEomjTypIndex==tagItem.uEomjTypIndex&&pItemData.sEmojContents==tagItem.sEmojContents&&pItemData.sMaskContents==tagItem.sMaskContents){
  113. pListItemModel->sort(0);
  114. this->setCurrentIndex(Index);
  115. return true;
  116. }
  117. }
  118. }
  119. QString strErr = tr("The data for the target attribute does not exist in the list");
  120. uErrMsg = strErr.toStdU16String();
  121. return false;
  122. }
  123. 实现QListView函数//
  124. void Lncf_MsgEmojiListv::setViewMode(ViewMode mode)
  125. {
  126. if(mode == QListView::ListMode)
  127. mode = QListView::IconMode;
  128. this->setContentsMargins(3,3,3,3);
  129. this->update();
  130. QListView::setViewMode(mode);
  131. }
  132. void Lncf_MsgEmojiListv::setSpacing(int space)
  133. {
  134. QListView::setSpacing(space);
  135. }
  136. void Lncf_MsgEmojiListv::setGridSize(const QSize &size)
  137. {
  138. int nSizeWidth = qMin(size.width(),size.height());
  139. if(nSizeWidth <16)
  140. nSizeWidth = 16;
  141. if(nSizeWidth >256)
  142. nSizeWidth = 256;
  143. pItemsDelegate->SetItemViewsSize(QSize(nSizeWidth,nSizeWidth));
  144. QListView::setGridSize(QSize(nSizeWidth,nSizeWidth));
  145. }
  146. /// 添加一个表情数据
  147. /// \brief AddMsgEmojiItems
  148. /// \param data :表情数据
  149. ///
  150. void Lncf_MsgEmojiListv::AddMsgEmojiItems(LNCFQCHATMASK_EMOJI data)
  151. {
  152. if(IsExistEmojItem(data))
  153. return;
  154. QString sName = QString::fromStdU16String(data.sMaskContents);
  155. auto pViewItem = new QStandardItem(sName);
  156. pViewItem->setData(false, LQEMOJLISTITEM_ROLE::MSGEMOJLIST_ACTIV);
  157. pViewItem->setData(false, LQEMOJLISTITEM_ROLE::MSGEMOJLIST_CLICK);
  158. pViewItem->setData(false, LQEMOJLISTITEM_ROLE::MSGEMOJLIST_HOVER);
  159. pViewItem->setData(QVariant::fromValue(data), LQEMOJLISTITEM_ROLE::MSGEMOJLIST_ITEMS);
  160. pListItemModel->appendRow(pViewItem);
  161. }
  162. /// 添加多个表情数据到列表
  163. /// 此操作不会删除已有数据,仅追加数据
  164. /// \brief AddEmojiItemList
  165. /// \param data
  166. ///
  167. void Lncf_MsgEmojiListv::AddEmojiItemList(std::vector<LNCFQCHATMASK_EMOJI> &vList)
  168. {
  169. for(size_t x=0;x<vList.size();x++){
  170. if(!IsExistEmojItem(vList[x])){
  171. //printf("%s\n",QString::fromStdU16String(vList[x].sEmojContents).toStdString().c_str());
  172. QString sName = QString::fromStdU16String(vList[x].sMaskContents);
  173. auto pViewItem = new QStandardItem(sName);
  174. pViewItem->setData(false, LQEMOJLISTITEM_ROLE::MSGEMOJLIST_ACTIV);
  175. pViewItem->setData(false, LQEMOJLISTITEM_ROLE::MSGEMOJLIST_CLICK);
  176. pViewItem->setData(false, LQEMOJLISTITEM_ROLE::MSGEMOJLIST_HOVER);
  177. pViewItem->setData(QVariant::fromValue(vList[x]), LQEMOJLISTITEM_ROLE::MSGEMOJLIST_ITEMS);
  178. pListItemModel->appendRow(pViewItem);
  179. }
  180. }
  181. }
  182. /// 设置表情列表数据
  183. /// 注意:此操作会删除已有项
  184. /// \brief SetEmojiItemList
  185. /// \param vList
  186. ///
  187. void Lncf_MsgEmojiListv::SetEmojiItemList(std::vector<LNCFQCHATMASK_EMOJI> &vList)
  188. {
  189. pListItemModel->clear();
  190. AddEmojiItemList(vList);
  191. }
  192. /// 删除列表项
  193. /// \brief RemoveListItems
  194. /// \param tItemInf:为指定的列表项数据结构
  195. /// \param uErrMsg :返回错误引用参数
  196. /// \return
  197. ///
  198. bool Lncf_MsgEmojiListv::RemoveListItems(LNCFQCHATMASK_EMOJI tItemInf,std::u16string &uErrMsg)
  199. {
  200. int rowCount = pListItemModel->rowCount();
  201. LNCFQCHATMASK_EMOJI pItemData;
  202. for(int i=0;i<rowCount;i++) //mIndex 是用来保存我加入项目的个数。。
  203. {
  204. QModelIndex Index = pListItemModel->index(i, 0);
  205. pItemData = pListItemModel->data(Index,LQEMOJLISTITEM_ROLE::MSGEMOJLIST_ITEMS).value<LNCFQCHATMASK_EMOJI>();
  206. if(pItemData.uEomjTypIndex==tItemInf.uEomjTypIndex&&pItemData.sEmojContents==tItemInf.sEmojContents&&pItemData.sMaskContents==tItemInf.sMaskContents){
  207. pListItemModel->removeRow(Index.row());
  208. pListItemModel->sort(0);
  209. return true;
  210. }
  211. }
  212. QString strErr = tr("The target data does not exist and cannot be deleted");
  213. uErrMsg = strErr.toStdU16String();
  214. return false;
  215. }

至此表情列表基本就完成了,根据上面的代码您可以复刻一个表情列表控件,自己在完成属性接口与信号连接即可使用

有关更多技术分享与交流请加QQ群:717743458。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/192765?site
推荐阅读
相关标签
  

闽ICP备14008679号