基于索引导航控件,根据索引对联系人分组,支持多种操作模式,允许自定义设置正则表达式判断号码运营商。

根据以往惯例,先上图

有关运营商正则匹配代码如下

/// 运营商正则列表
/// 注意:暂未使用,可自行实现,默认顺序为0中国移动,1中国联通,2中国电信
/// \brief sIspNumRegexList
///
QList<QString> Lncf_NavCharHelper::sIspNumRegexList = QList<QString>()<<"^(086|086\\ |086\\-|\\+86|86|\\+86\\ |\\+86\\-|86\\-|86\\ |)1(3([4-9])|4([7-8]|40)|5([0-2]|[7-9])|7(8|03|05|06)|8([2-4]|[7-8])|9(8))\\d{7,8}$"<<"(086|086\\ |086\\-|\\+86|86|\\+86\\ |\\+86\\-|86\\-|86\\ |)1(3([0-2])|4([5-6])|5([5-6])|6([6-7])|7([5-6]|04|07|08|09|10|11|12|13|14|15|16|17|18|19)|8([5-6]))\\d{7,8}$"<<"^(086|086\\ |086\\-|\\+86|86|\\+86\\ |\\+86\\-|86\\-|86\\ |)1(3([3]|[49])|4(10)|5(3)|7([7|00|01|02|40])|8([0-1]|[9])|9([1|9]))\\d{7,8}$";/// 获取电话号码运营商
/// \brief GetPhoneNumIspIndex
/// \param sText
/// \return
///
uint Lncf_NavCharHelper::GetPhoneNumIspIndex(QString sText)
{uint uCount = sIspNumRegexList.count();for(uint i=0;i<uCount;i++){std::regex rPhoneNum(sIspNumRegexList[i].toStdString());if(std::regex_match(sText.toStdString(), rPhoneNum)){return i;}}return 65535;//65535标识未知运营商
}/// 添加运营商号码段正则匹配
/// \brief AddIspNumRegexDatas
/// \param sText
///
uint Lncf_NavCharHelper::AddIspNumRegexDatas(QString sText)
{if(!sText.isEmpty()){sIspNumRegexList.insert(sIspNumRegexList.count(),sText);return sIspNumRegexList.count()-1;}return 0;
}

自定义属性结构定义如下

 /// 通讯录列表项风格委托样式数据结构///typedef struct LQCONTACTLIST_STYLE_{QColor    cGroupBkgColor = QColor(88,88,88,44);   //分组背景色QColor    cGroupExpanClr = QColor(77,77,77,44);   //分组展开背景色QColor    cGroupHoverClr = QColor(0,0,9,66);    //分组鼠标悬停背景颜色QColor    cGroupExpHover = QColor(0,0,9,33);   //分组展开悬停背景色QColor    cGroupsBorders = QColor(117,131,218);   //分组边框颜色QColor    cItemsBkgColor = Qt::transparent;//联系人背景色QColor    cItemsHoverClr = QColor(69,176,142);    //联系人鼠标悬停背景色QColor    cItemSelectClr = QColor(244,123,64);    //联系人选中背景色QColor    cIconHoverClrs = QColor(22,22,22,44);   //鼠标悬停颜色QColor    cIconSelectClr = QColor(11,11,11,44);   //选中项时颜色QColor    cItemNamesClrs = QColor(33,33,33);      //联系人名称文字颜色QColor    cNameHoverClrs = QColor(220,220,220);   //联系人名称文字鼠标悬停时颜色QColor    cNameSelectClr = QColor(255,255,255);   //联系人名称文字选中时颜色QColor    cGroupTxtColor = QColor(44,44,44);       //分组背景色QColor    cGroupHoverTxt = QColor(255,255,255);    //分组鼠标悬停背景颜色QColor    cGroupExpanTxt = QColor(33,33,33);       //分组鼠标悬停背景颜色QColor    cItemsTxtColor = QColor(33,33,33);       //联系人文字颜色QColor    cItemsHoverTxt = QColor(255,255,255);    //联系人鼠标悬停文字色QColor    cItemSelectTxt = QColor(235,235,235);    //联系人选中文字色QColor    cGroupCountBkg = QColor(127,127,127,127);    //分组成员统计背景颜色QColor    cGroupCountTxt = QColor(220,220,220);    //分组成员统计文字颜色QColor    cGroupNodeClrs = QColor(127,127,127);    //分组节点图标颜色QColor    cGroupNodeBkgd = QColor(58,191,136);     //分组节点背景颜色QColor    cGroupNodesExp = QColor(114,133,218);    //分组节点展开背景颜色QColor    cDescHoverClrs = QColor(144,144,144);    //摘要文字鼠标悬停颜色QColor    cDescSelectClr = QColor(200,200,200);    //摘要文字选中颜色QColor    cItemSplitLine = QColor(63,166,148,66);  //分割线颜色QColor    cAvatarFrmClrs = QColor(250,74,33);      //头像边框颜色QColor    cMouseHoverBkg = QColor(124,144,218);    //鼠标悬停背景颜色QColor    cAvatarBkgClrs = QColor(55,55,55);       //头像背景填充颜色QColor    cIspLogoBkgClr = QColor(192,192,192,127);     //ISP节点颜色QColor    cOptionBkgClrs = QColor(248,148,72);    //选项按钮背景颜色QColor    cCallBkgndClrs = QColor(130,144,228);   //呼叫按钮悬停颜色QColor    cInviteBkgClrs = QColor(71,186,152);    //邀请按钮悬停颜色QColor    cSentMailBgClr = QColor(89,83,170);    //发送邮件按钮悬停颜色QColor    cChatMsgBkgClr = QColor(128,173,88);    //发起会话按钮悬停颜色QColor    cOptionHoveClr = QColor(248,74,99);     //选项按钮悬停颜色QColor    cAnimateColors = QColor(44,44,44,44);   //点击动画效果背景颜色uint      uDescPrioritys =0;                      //摘要优先级,0手机号码,2电子邮件,3固话,4地址,5存根bool      bRoundActiveBg = true;                  //选中背景是否绘制成半圆uint      uRoundActivPos = 0;                     //半圆背景位置,0左侧,1右侧bool      bShowSplitLine = false;                 //是否显示分割线uint      nSplitLineType = 2;                     //分割线样式,0实线,1虚线,2点线,3点划线,4双点划线uint      nHeadeLineType = 2;                     //标头参考线样式,0实线,1虚线,2点线,3点划线,4双点划线bool      bIconViewModel = false;                 //是否为列表视图,默认是uint      uItemHeightVal = 50;                    //行高uint      uItemMinHeight = 34;                    //小图标模式行高uint      uGroupsHeights = 26;                    //分组行高uint      uIconGridWidth = 72;                    //ICON视图格子宽度uint      uIconGridHeigh = 100;                   //ICON视图格子高度uint      uGroupStyleIds = 0;                     //分组风格,0默认风格,1居中uint      uGroupBorderId = 3;                     //分组边框风格,0不显示边框,1全部边框,2上,3下float     fBordersWidths = 0.5;                   //边框宽度double    dGroupRadiusId = 0;                     //分组边框半径uint      uItemsStyleIds = 0;                     //列表项风格,0大图标模式,1小图标模式uint      uHorizeMarginG = 0;                     //分组项水平Marginuint      uVerticMarginG = 0;                     //分组项垂直Marginuint      uHorizeMarginU = 0;                     //联系人项水平Marginuint      uVerticMarginU = 0;                     //联系人项垂直Margindouble    dAvatarsRadius = 0.5;                   //联系人头像圆角半径bool      bHasGroupArrow = false;                 //是否使用分组箭头,默认为否,显示圆点uint      uLogoStylesIds = 1;                     //摘要logo类型,0图标,1文字,其它不显示bool      bShowUserCount = true;                  //是否显示分组成员统计bool      bIsShowSummary = true;                  //显示用户摘要,如果为false则表示显示来源bool      bShowOptionBtn = true;                  //是否绘制选项按钮bool      bIsShowCallBtn = true;                  //是否显示呼叫按钮bool      bIsShowMailBtn = true;                  //是否显示发送邮件按钮bool      bShowInviteBtn = true;                  //是否显示邀请按钮bool      bIsShowChatBtn = true;                  //是否显示会话按钮bool      bIsShowMoreBtn = true;                  //是否显示自定义处理按钮bool      bRandomAvbgClr = true;                  //在显示文字头像事是否使用随机背景颜色uint      bAvatarsStyles = 0;                     //头像显示风格索引,0仅显示图像,无头像图像时显示默认头像,1无图像时显示名称第一字符,2仅显示名称第一字符bool operator == (const LQCONTACTLIST_STYLE_& rhs) // == 操作运算符重载{return (cGroupBkgColor == rhs.cGroupBkgColor)   //分组背景色&& (cGroupExpanClr == rhs.cGroupExpanClr)       //分组展开背景色&& (cGroupHoverClr == rhs.cGroupHoverClr)       //分组鼠标悬停背景颜色&& (cGroupExpHover == rhs.cGroupExpHover)       //分组展开悬停背景色&& (cGroupsBorders == rhs.cGroupsBorders)       //分组边框颜色&& (cItemsBkgColor == rhs.cItemsBkgColor)       //联系人背景色&& (cItemsHoverClr == rhs.cItemsHoverClr)       //联系人鼠标悬停背景色&& (cItemSelectClr == rhs.cItemSelectClr)       //联系人选中背景色&& (cIconHoverClrs == rhs.cIconHoverClrs)       //鼠标悬停颜色&& (cIconSelectClr == rhs.cIconSelectClr)       //选中项时颜色&& (cItemNamesClrs == rhs.cItemNamesClrs)       //联系人名称文字颜色&& (cNameHoverClrs == rhs.cNameHoverClrs)       //联系人名称文字鼠标悬停时颜色&& (cNameSelectClr == rhs.cNameSelectClr)       //联系人名称文字选中时颜色&& (cGroupTxtColor == rhs.cGroupTxtColor)       //分组背景色&& (cGroupHoverTxt == rhs.cGroupHoverTxt)       //分组鼠标悬停背景颜色&& (cGroupExpanTxt == rhs.cGroupExpanTxt)       //分组鼠标悬停背景颜色&& (cItemsTxtColor == rhs.cItemsTxtColor)       //联系人文字颜色&& (cItemsHoverTxt == rhs.cItemsHoverTxt)       //联系人鼠标悬停文字色&& (cItemSelectTxt == rhs.cItemSelectTxt)       //联系人选中文字色&& (cGroupCountBkg == rhs.cGroupCountBkg)       //分组成员统计背景颜色&& (cGroupCountTxt == rhs.cGroupCountTxt)       //分组成员统计文字颜色&& (cGroupNodeClrs == rhs.cGroupNodeClrs)       //分组节点图标颜色&& (cGroupNodeBkgd == rhs.cGroupNodeBkgd)       //分组节点背景颜色&& (cGroupNodesExp == rhs.cGroupNodesExp)       //分组节点展开背景颜色&& (cDescHoverClrs == rhs.cDescHoverClrs)       //摘要文字鼠标悬停颜色&& (cDescSelectClr == rhs.cDescSelectClr)       //摘要文字选中颜色&& (cItemSplitLine == rhs.cItemSplitLine)       //分割线颜色&& (cAvatarFrmClrs == rhs.cAvatarFrmClrs)       //头像边框颜色&& (cMouseHoverBkg == rhs.cMouseHoverBkg)       //鼠标悬停背景颜色&& (cAvatarBkgClrs == rhs.cAvatarBkgClrs)       //头像背景填充颜色&& (cIspLogoBkgClr == rhs.cIspLogoBkgClr)       //ISP节点颜色&& (cOptionBkgClrs == rhs.cOptionBkgClrs)       //选项按钮背景颜色&& (cCallBkgndClrs == rhs.cCallBkgndClrs)       //呼叫按钮悬停颜色&& (cInviteBkgClrs == rhs.cInviteBkgClrs)       //邀请按钮悬停颜色&& (cSentMailBgClr == rhs.cSentMailBgClr)       //发送邮件按钮悬停颜色&& (cChatMsgBkgClr == rhs.cChatMsgBkgClr)       //发起会话按钮悬停颜色&& (cOptionHoveClr == rhs.cOptionHoveClr)       //选项按钮悬停颜色&& (uDescPrioritys == rhs.uDescPrioritys)       //摘要优先级,0手机号码,2电子邮件,3固话,4地址,5存根&& (bRoundActiveBg == rhs.bRoundActiveBg)       //选中背景是否绘制成半圆&& (bShowSplitLine == rhs.bShowSplitLine)       //是否显示分割线&& (uRoundActivPos == rhs.uRoundActivPos)&& (nSplitLineType == rhs.nSplitLineType)       //分割线样式,0实线,1虚线,2点线,3点划线,4双点划线&& (nHeadeLineType == rhs.nHeadeLineType)       //标头参考线样式,0实线,1虚线,2点线,3点划线,4双点划线&& (bIconViewModel == rhs.bIconViewModel)       //是否为列表视图,默认是&& (uItemHeightVal == rhs.uItemHeightVal)       //行高&& (uItemMinHeight == rhs.uItemMinHeight)       //小图标模式行高&& (uGroupsHeights == rhs.uGroupsHeights)       //分组行高&& (uIconGridWidth == rhs.uIconGridWidth)       //ICON视图格子宽度&& (uIconGridHeigh == rhs.uIconGridHeigh)       //ICON视图格子高度&& (uGroupStyleIds == rhs.uGroupStyleIds)       //分组风格,0默认风格,1居中&& (uGroupBorderId == rhs.uGroupBorderId)       //分组边框风格,0不显示边框,1全部边框,2上,3下&& (fBordersWidths == rhs.fBordersWidths)       //边框宽度&& (dGroupRadiusId == rhs.dGroupRadiusId)       //分组边框半径&& (uItemsStyleIds == rhs.uItemsStyleIds)       //列表项风格,0大图标模式,1小图标模式&& (uHorizeMarginG == rhs.uHorizeMarginG)       //分组项水平Margin&& (uVerticMarginG == rhs.uVerticMarginG)       //分组项垂直Margin&& (uHorizeMarginU == rhs.uHorizeMarginU)       //联系人项水平Margin&& (uVerticMarginU == rhs.uVerticMarginU)       //联系人项垂直Margin&& (dAvatarsRadius == rhs.dAvatarsRadius)       //联系人头像圆角半径&& (bHasGroupArrow == rhs.bHasGroupArrow)       //是否显示分组箭头&& (uLogoStylesIds == rhs.uLogoStylesIds)       //运行商logo类型,0图标,1文字&& (bShowUserCount == rhs.bShowUserCount)       //是否显示分组成员统计&& (bIsShowSummary == rhs.bIsShowSummary)       //显示用户摘要,如果为false则表示显示来源&& (bShowOptionBtn == rhs.bShowOptionBtn)       //是否显示选项按钮&& (bIsShowCallBtn == rhs.bIsShowCallBtn)       //是否显示呼叫按钮&& (bIsShowMailBtn == rhs.bIsShowMailBtn)       //是否显示发送邮件按钮&& (bShowInviteBtn == rhs.bShowInviteBtn)       //是否显示邀请按钮&& (bIsShowChatBtn == rhs.bIsShowChatBtn)       //是否显示会话按钮&& (bIsShowMoreBtn == rhs.bIsShowMoreBtn)       //是否显示自定义处理按钮&& (bRandomAvbgClr == rhs.bRandomAvbgClr)       //在显示文字头像事是否使用随机背景颜色&& (bAvatarsStyles == rhs.bAvatarsStyles);      //头像显示风格索引,0仅显示图像,无头像图像时显示默认头像,1无图像时显示名称第一字符,2仅显示名称第一字符}bool operator != (const LQCONTACTLIST_STYLE_& rhs) // != 操作运算符重载{return !(*this == rhs);}}LQCONTACTLIST_STYLE,*PLQCONTACTLIST_STYLE;

绘制委托定义主要代码如下

class LNCF_QTSOCIALLIBS_API Lncf_QContactItemd:public Lncf_QListDelegate{Q_OBJECTpublic:explicit Lncf_QContactItemd(QObject *parent = nullptr);~Lncf_QContactItemd();private:/// 初始化通讯录列表委托/// \brief InitContactItemd///void InitContactItemd();private:/// 通讯录列表项风格委托样式数据结构变量/// \brief tDelegateStyle///LQCONTACTLIST_STYLE  tDelegateStyle;std::u16string       sOtherAppIcons;   //其它应用图标std::u16string       sSourceAppsImg;   //默认来源应用图标std::u16string       sGroupExpanImg;   //分组展开图标std::u16string       sGroupCloseImg;   //分组关闭图标std::u16string       sCallNumberImg;   //呼叫号码图标std::u16string       sSentChatImage;   //发起会话图标std::u16string       sSentMailImage;   //发送邮件图标std::u16string       sInviteRegImgs;   //邀请注册图标std::u16string       sMoreOptionImg;   //更多选项图标std::u16string       sLocationImage;   //位置图标QList<std::u16string> sIspLogosLists;  //运营商Logo列表,0未知,1移动,2联通,3电信,可自行添加或更改QList<std::u16string> sIspNamesLists;  //运营商名称列表QList<QColor>        vRandomClolors;   //随机颜色列表QImage               pGroupExpanImg;   //分组展开图标对象QImage               pGroupCloseImg;   //分组收起图标对象private:/// 重写系统绘制void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE;/// 绘制背景/// \brief DrawBackgrounds/// \param painter/// \param option/// \param bGroup/// \param bExpand///void DrawBackgrounds(QPainter *painter,const QStyleOptionViewItem &option, const QModelIndex &index,bool bGroup,bool bExpand) const;/// 绘制分组项/// \brief DrawItemsGroups/// \param painter      :绘图引擎指针/// \param option       :视图风格选项引用参数/// \param groupData    :索引分组列表视图数据结构参数///void DrawItemsGroups(QPainter *painter,const QStyleOptionViewItem &option,bool bExpand,LQNAVLISTVIEW_GROUP groupData) const;/// 绘制通讯录联系人项/// \brief DrawItemContact/// \param painter      :绘图引擎指针/// \param option       :视图风格选项引用参数/// \param itemsData    :通讯录联系人视图数据结构参数///void DrawItemContact(QPainter *painter,const QStyleOptionViewItem &option, const QModelIndex &index,LNCFQCONTACT_LISTVIEWS itemsData) const;/// 绘制头像/// \brief DrawItemsAvatar/// \param painter/// \param option/// \param sImagePath/// \param bHover/// \param sName///void DrawItemsAvatar(QPainter *painter,const QStyleOptionViewItem &option,std::u16string sImagePath,bool bHover,std::u16string sName=u"") const;/// 绘制显示名/// \brief DrawDisplayName/// \param painter/// \param option/// \param sName///void DrawDisplayName(QPainter *painter,const QStyleOptionViewItem &option,std::u16string sName) const;/// 绘制联系人摘要信息 第一号码或Email/// \brief DrawUserSummary/// \param painter/// \param option/// \param sDesc/// \param uType   :描述信息类别,0电话号码,1电子邮件,2地址信息///void DrawUserSummary(QPainter *painter,const QStyleOptionViewItem &option,std::u16string sDesc ,uint uType) const;/// 绘制来源信息/// \brief DrawSourcesInfo/// \param painter/// \param option/// \param sName/// \param sImage///void DrawSourcesInfo(QPainter *painter,const QStyleOptionViewItem &option,std::u16string sName,std::u16string sImage) const;/// 绘制选项图标/// \brief DrawOptionsBtns/// \param painter/// \param option/// \param uHover    :鼠标移动的控件索引,0无,1音频通话,2视频通话,3更多/// \param bCall     :是否绘制呼叫快速按钮/// \param bEmail    :是否绘制发送邮件快速按钮/// \param bChat     :是否绘制发起会话快速按钮/// \param bInvite   :是否绘制发送邀请快速按钮///void DrawOptionsBtns(QPainter *painter,const QStyleOptionViewItem &option,uint uHover,bool bCall,bool bEmail,bool bChat,bool bInvite) const;/// 绘制分割线/// \brief DrawSplitupLine/// \param painter/// \param option///void DrawSplitupLine(QPainter *painter,const QStyleOptionViewItem &option) const;
//属性代码省略
};

部分主要绘制代码如下

/// 重写系统绘制void Lncf_QContactItemd::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const{if(index.isValid()){painter->save();painter->setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);painter->setPen(Qt::NoPen);//判断是分组还是用户if(index.data(LQCONTACTLIST_ROLES::CONTACTLIST_HEADE).toBool()){//绘制分组项目bool  bHasExpand = index.data(LQCONTACTLIST_ROLES::CONTACTLIST_EXPAN).toBool();QVariant  varGroup = index.data(LQCONTACTLIST_ROLES::CONTACTLIST_GROUP);LQNAVLISTVIEW_GROUP ItemGroupData = varGroup.value<LQNAVLISTVIEW_GROUP>();//绘制背景DrawBackgrounds(painter,option,index,true,bHasExpand);//绘制分组DrawItemsGroups(painter,option,bHasExpand,ItemGroupData);}else{//绘制通讯录联系人项目QVariant  varContact = index.data(LQCONTACTLIST_ROLES::CONTACTLIST_ITEMS);LNCFQCONTACT_LISTVIEWS ItemContactData = varContact.value<LNCFQCONTACT_LISTVIEWS>();DrawBackgrounds(painter,option,index,false,false);DrawItemContact(painter,option,index,ItemContactData);}painter->restore();}}/// 绘制通讯录联系人项/// \brief DrawItemContact/// \param painter      :绘图引擎指针/// \param option       :视图风格选项引用参数/// \param itemsData    :通讯录联系人视图数据结构参数///void Lncf_QContactItemd::DrawItemContact(QPainter *painter,const QStyleOptionViewItem &option, const QModelIndex &index,LNCFQCONTACT_LISTVIEWS itemsData) const{painter->save();//绘制头像DrawItemsAvatar(painter,option,itemsData.sAvatarImgPath,index.data(LQCONTACTLIST_ROLES::CONTACTLOGO_HOVER).toBool(),itemsData.sItemsShowName);//绘制联系人名称DrawDisplayName(painter,option,itemsData.sItemsShowName);// 绘制摘要信息,号码或Email或地址if(option.rect.height()>41){uint descType = 0;std::u16string uContactDesc;if(!itemsData.sItemOneNumber.empty())uContactDesc = itemsData.sItemOneNumber;else{if(!itemsData.sItemMailValue.empty()){uContactDesc = itemsData.sItemMailValue;descType = 1;}else{if(!itemsData.sItemAddresses.empty()){uContactDesc = itemsData.sItemAddresses;descType = 2;}}}if(!tDelegateStyle.bIconViewModel&&!uContactDesc.empty())this->DrawUserSummary(painter,option,uContactDesc,descType);else{if(!tDelegateStyle.bIconViewModel&&!itemsData.sItemStubValue.empty())this->DrawSourcesInfo(painter,option,itemsData.sItemStubValue,itemsData.sItemStubImage);}}// 绘制选项图标if(!this->tDelegateStyle.bIconViewModel&&this->tDelegateStyle.bShowOptionBtn){/// \param bCall     :是否绘制呼叫快速按钮/// \param bEmail    :是否绘制发送邮件快速按钮/// \param bChat     :是否绘制发起会话快速按钮/// \param bInvite   :是否绘制发送邀请快速按钮/////鼠标移动的控件索引,0无,1呼叫,2邮件,3会话,4邀请,5更多uint uOptionHover = 0;if(index.data(LQCONTACTLIST_ROLES::CONTACTCALL_HOVER).toBool())uOptionHover =1;else if(index.data(LQCONTACTLIST_ROLES::CONTACTMAIL_HOVER).toBool())uOptionHover =2;else if(index.data(LQCONTACTLIST_ROLES::CONTACTCHAT_HOVER).toBool())uOptionHover =3;else if(index.data(LQCONTACTLIST_ROLES::CONTACTINVITE_HOVER).toBool())uOptionHover =4;else{if(index.data(LQCONTACTLIST_ROLES::CONTACTMORE_HOVER).toBool())uOptionHover =5;}DrawOptionsBtns(painter,option,uOptionHover,!itemsData.sItemOneNumber.empty()||!itemsData.sItemsTelphone.empty(),!itemsData.sItemMailValue.empty(),itemsData.gUserStubIdVal != uNullUuidVal?true:false,itemsData.gUserStubIdVal == uNullUuidVal);}// 绘制分割线if(!this->tDelegateStyle.bIconViewModel&&tDelegateStyle.bShowSplitLine)DrawSplitupLine(painter,option);painter->restore();}/// 绘制显示名/// \brief DrawDisplayName/// \param painter/// \param option/// \param sName///void Lncf_QContactItemd::DrawDisplayName(QPainter *painter,const QStyleOptionViewItem &option,std::u16string sName) const{painter->save();QRect  rcName,rcText;if(!tDelegateStyle.bIconViewModel){int leftMargin=option.rect.left()+option.rect.height();rcName = QRect(leftMargin, option.rect.top()+(option.rect.height()>41?5:0), option.rect.width()-leftMargin, option.rect.height()>41?20:option.rect.height());rcText= rcName;}else{rcName = QRect(option.rect.left()+1,  option.rect.top()+option.rect.width(), option.rect.width()-2, 20);rcText = QRect(rcName.left()+4,rcName.top(),rcName.width()-8,rcName.height());}painter->setPen(this->tDelegateStyle.cItemsTxtColor);// 鼠标悬停或者选中时改变背景色painter->setPen(QPen(tDelegateStyle.cItemNamesClrs));if (option.state.testFlag(QStyle::State_MouseOver)) {painter->setPen(Qt::NoPen);painter->setBrush(tDelegateStyle.cItemsHoverClr);if(tDelegateStyle.bIconViewModel)painter->drawRoundedRect(rcName, rcName.height()/2, rcName.height()/2);painter->setPen(QPen(tDelegateStyle.cNameHoverClrs));}if (option.state.testFlag(QStyle::State_Selected)) {painter->setPen(Qt::NoPen);painter->setBrush(tDelegateStyle.cItemSelectClr);if(tDelegateStyle.bIconViewModel)painter->drawRoundedRect(rcName, rcName.height()/2, rcName.height()/2);painter->setPen(QPen(tDelegateStyle.cNameSelectClr));}QFont fontObj=painter->font();fontObj.setPixelSize(12);QFontMetrics fontMetrics(fontObj);painter->setFont(fontObj);QString szName = QString::fromStdU16String(sName);QString sShowName=fontMetrics.elidedText(szName,Qt::ElideRight,rcText.width());painter->drawText(rcText,tDelegateStyle.bIconViewModel?Qt::AlignCenter:Qt::AlignVCenter,sShowName);painter->restore();}/// 绘制联系人摘要信息 第一号码或Email/// \brief DrawUserSummary/// \param painter/// \param option/// \param sDesc/// \param uType  :描述信息类别,0电话号码,1电子邮件,2地址信息///void Lncf_QContactItemd::DrawUserSummary(QPainter *painter,const QStyleOptionViewItem &option,std::u16string sDesc,uint uType) const{//uLogoStylesIds 摘要logo类型,0图标,1文字,其它不显示painter->save();uint uIspIndex = 65535;if(uType==0&&(tDelegateStyle.uLogoStylesIds==0||tDelegateStyle.uLogoStylesIds==1)){uIspIndex= Lncf_NavCharHelper::GetPhoneNumIspIndex(QString::fromStdU16String(sDesc));}int leftMargin=option.rect.left()+option.rect.height()+((tDelegateStyle.uLogoStylesIds==0?20:0||tDelegateStyle.uLogoStylesIds==1?44:0));QRectF descRect = QRect(leftMargin, option.rect.bottom()-24, option.rect.width()-leftMargin, 18);QRectF descLogoFrm = QRectF(option.rect.left()+option.rect.height(),option.rect.bottom()-20,tDelegateStyle.uLogoStylesIds==0?14:42,14);QRectF descLogo = QRectF(descLogoFrm.left()+1,descLogoFrm.top()+1,descLogoFrm.width()-2,descLogoFrm.height()-2);QString sMsgText;if(sDesc.empty())sMsgText = tr("Contact summary data is empty");elsesMsgText=QString::fromStdU16String(sDesc);QFont fontObj=painter->font();fontObj.setPointSize(7);painter->setFont(fontObj);///在前面绘制运营商或Email图标/// 0电话号码,1电子邮件,2地址信息if(tDelegateStyle.uLogoStylesIds==0){painter->setPen(Qt::NoPen);painter->setBrush(tDelegateStyle.cIspLogoBkgClr);painter->drawRoundedRect(descLogoFrm,descLogoFrm.height()/2,descLogoFrm.height()/2);painter->setPen(QPen(tDelegateStyle.cItemsTxtColor));painter->setFont(fontObj);switch (uType) {case 0:{if(uIspIndex>=0&&uIspIndex<sIspNamesLists.count())painter->drawImage(descLogo,QImage(QString::fromStdU16String(sIspLogosLists[uIspIndex+1])));else painter->drawImage(descLogo,QImage(QString::fromStdU16String(sIspLogosLists[0])));}break;case 1:{painter->drawImage(descLogo,QImage(QString::fromStdU16String(sSentMailImage)));}break;case 2:{painter->drawImage(descLogo,QImage(QString::fromStdU16String(sLocationImage)));}break;}}if(tDelegateStyle.uLogoStylesIds==1){painter->setPen(Qt::NoPen);painter->setBrush(tDelegateStyle.cIspLogoBkgClr);painter->drawRoundedRect(descLogoFrm,descLogoFrm.height()/2,descLogoFrm.height()/2);painter->setPen(QPen(tDelegateStyle.cItemsTxtColor));switch (uType) {case 0:{if(uIspIndex>=0&&uIspIndex<sIspNamesLists.count())painter->drawText(descLogo,Qt::AlignCenter,QString::fromStdU16String(sIspNamesLists[uIspIndex+1]));else painter->drawText(descLogo,Qt::AlignCenter,QString::fromStdU16String(sIspNamesLists[0]));}break;case 1:{painter->drawText(descLogo,Qt::AlignCenter,tr("MAIL"));}break;case 2:{painter->drawText(descLogo,Qt::AlignCenter,tr("ADDR"));}break;}}painter->setPen(QPen(tDelegateStyle.cItemsTxtColor));if (option.state.testFlag(QStyle::State_MouseOver)) {painter->setPen(QPen(tDelegateStyle.cDescHoverClrs));}if (option.state.testFlag(QStyle::State_Selected)) {painter->setPen(QPen(tDelegateStyle.cDescSelectClr));}fontObj.setPointSize(8);QFontMetrics fontMetrics(fontObj);painter->setFont(fontObj);sMsgText=fontMetrics.elidedText(sMsgText,Qt::ElideRight,descRect.width());painter->drawText(descRect,Qt::AlignLeft|Qt::AlignBottom, sMsgText);painter->restore();}/// 绘制来源信息/// \brief DrawSourcesInfo/// \param painter/// \param option/// \param sName/// \param sImage///void Lncf_QContactItemd::DrawSourcesInfo(QPainter *painter,const QStyleOptionViewItem &option,std::u16string sName,std::u16string sImage) const{painter->save();int leftMargin=option.rect.left()+option.rect.height();QRectF logoRect = QRect(leftMargin, option.rect.bottom()-24, 16, 16);QRectF msgsRect = QRect(leftMargin+18, option.rect.bottom()-24, option.rect.width()-leftMargin, 18);QImage imgIcon = sImage.empty()?QImage(QString::fromStdU16String(sSourceAppsImg)):QImage(QString::fromStdU16String(sImage));if(imgIcon.isNull())imgIcon = QImage(QString::fromStdU16String(sSourceAppsImg));painter->drawImage(logoRect, imgIcon);painter->setPen(QPen(tDelegateStyle.cItemsTxtColor));if (option.state.testFlag(QStyle::State_MouseOver)) {painter->setPen(QPen(tDelegateStyle.cDescHoverClrs));}if (option.state.testFlag(QStyle::State_Selected)) {painter->setPen(QPen(tDelegateStyle.cDescSelectClr));}QString sMsgText = tr("Stub Apps:");if(sName.empty())sMsgText = tr("Unknown Stub App source");elsesMsgText+=QString::fromStdU16String(sName);QFont fontObj=painter->font();fontObj.setPixelSize(msgsRect.height()/1.7);QFontMetrics fontMetrics(fontObj);painter->setFont(fontObj);sMsgText=fontMetrics.elidedText(sMsgText,Qt::ElideRight,msgsRect.width());painter->drawText(msgsRect,Qt::AlignLeft|Qt::AlignVCenter, sMsgText);painter->restore();}

有关ListView定义主要代码如下

 class LNCF_QTSOCIALLIBS_API Lncf_QContactListv :public Lncf_IndexNavListv{Q_OBJECTQ_PROPERTY(QString sOtherAppIcons READ GetOtherAppIcons WRITE SetOtherAppIcons)   //其它应用图标Q_PROPERTY(QString sSourceAppsImg READ GetSourceAppsImg WRITE SetSourceAppsImg)   //默认来源应用图标Q_PROPERTY(QString sGroupExpanImg READ GetGroupExpanImg WRITE SetGroupExpanImg)   //分组展开图标Q_PROPERTY(QString sGroupCloseImg READ GetGroupCloseImg WRITE SetGroupCloseImg)   //分组关闭图标Q_PROPERTY(QString sCallNumberImg READ GetCallNumberImg WRITE SetCallNumberImg)   //呼叫号码图标Q_PROPERTY(QString sSentChatImage READ GetSentChatImage WRITE SetSentChatImage)   //发起会话图标Q_PROPERTY(QString sSentMailImage READ GetSentMailImage WRITE SetSentMailImage)   //发送邮件图标Q_PROPERTY(QString sInviteRegImgs READ GetInviteRegImgs WRITE SetInviteRegImgs)   //邀请注册图标Q_PROPERTY(QString sMoreOptionImg READ GetMoreOptionImg WRITE SetMoreOptionImg)   //更多选项图标Q_PROPERTY(bool    bHasMouseEvent READ GetHasMouseEvent WRITE SetHasMouseEvent)   //是否启用鼠标事件Q_PROPERTY(bool    bHasHoverEvent READ GetHasHoverEvent WRITE SetHasHoverEvent)   //是否处理鼠标悬停事件Q_PROPERTY(bool    bShowItemsTips READ GetShowItemsTips WRITE SetShowItemsTips)   //是否显示鼠标悬停时提示信息Q_PROPERTY(bool    bHasShowGroups READ GetHasShowGroups WRITE SetHasShowGroups)   //是否显示分组public:explicit Lncf_QContactListv(QWidget *parent = nullptr);~Lncf_QContactListv();public:/// 初始化列表虚函数/// \brief InitContactList/// \param bGrid :是否为窗格导航风格///virtual void InitContactList(bool bGrid=false);/// 重初始化封面布局,必须先调用此函数/// \brief InitCoverLayout/// \param btnList/// \param bHorizeOption/// \param sImgPath/// \param sTitle/// \param sLoadTip/// \param sDesc///void InitCoversLayout(QList<LQCOVEROPTION_BNINF> btnList=QList<LQCOVEROPTION_BNINF>(),bool bHorizeOption = true,std::u16string sImgPath= u"", std::u16string sTitle=u"",std::u16string sLoadTip=u"",std::u16string sDesc=u"") override;private:/// 初始化分组/// \brief InitContactGroup///void InitContactGroup();private:QStandardItemModel *pListItemModel = nullptr;    //列表模型对象指针Lncf_QContactItemd *pItemsDelegate = nullptr;    //列表项委托对象指针Lncf_QContactSortm *pSortFilteMode = nullptr;    //列表筛选器模型对象指针/// 是否启用鼠标跟踪/// \brief bMouseTracking///bool                bMouseTracking = false;/// 是否显示分组/// \brief bHasShowGroups///bool                bHasShowGroups = true;/// 分组是否已经初始化/// \brief bInitGroupItem///bool                bInitGroupItem = false;/// 索引分组文本/// \brief sNaviTextsList///QList<std::u16string>   sNaviTextsList;public:/// 添加通讯录联系人项目/// \brief AddContactDatas/// \param data     :默认视图数据///void AddContactDatas(LNCFQCONTACT_LISTVIEWS data);/// 添加通讯录联系人集合/// 注意:此函数不会清空列表,追加数据,如果存在相同属性的数据则不会被添加/// \brief AddContactsList/// \param data///void AddContactsList(std::vector<LNCFQCONTACT_LISTVIEWS> data);/// 设置通讯录联系人列表数据集合/// 注意:此函数会清空列表,并重置数据/// \brief SetContactsList/// \param vList///void SetContactsList(std::vector<LNCFQCONTACT_LISTVIEWS> &vList);/// 删除通讯录联系人/// \brief RemovesContacts/// \param tUserInf/// \param uErrMsg/// \return///bool RemovesContacts(LNCFQCONTACT_LISTVIEWS tUserInf,QString &uErrMsg);/// 检查目标联系人属性是否存在,检查三个itemid属性/// \brief HasContactExist/// \param data,主要用结构体三个参数:存根ID/// \return///bool HasContactExist(LNCFQCONTACT_LISTVIEWS data);/// 更新用户数据/// \brief UpdateUserDatas/// \param data     :默认视图数据///bool UpdatedContacts(LNCFQCONTACT_LISTVIEWS data,QString &uErrMsg);/// 根据模型索引更新模型联系人数据/// \brief UpdatedContacts/// \param index    :索引ID/// \param data     :视图数据///bool UpdatedContacts(const QModelIndex &index,LNCFQCONTACT_LISTVIEWS data,QString &uErrMsg);/// 激活指定的联系人项/// \brief ActivedContacts/// \param tagContact///bool ActivedContacts(const LNCFQCONTACT_LISTVIEWS tagContact,QString &uErrMsg);/// 更新列表数据/// \brief UpdatedListDatas///void UpdatedListDatas();//属性代码省略
};

使用者连接信号定义如下

/// 列表分组展开或收起/// \brief GroupItemsExpand/// \param bExpand 是否展开,true表示展开否则为收起/// \param uIndex :首字母索引ID/// \param index  :模型索引ID///void GroupsItemExpand(const bool &bExpand,const uint64_t uIndex, const QModelIndex &index);/// 列表视图元素单击事件信号/// \brief ItemElementClick/// \param nElement 元素索引定义 0:头像区域,1呼叫按钮区域,2发送邮件按钮区域,3发起会话按钮区域,4发送邀请按钮区域,5更多选项按钮区域/// \param index///void ItemElementClick(const int &nElement,const QModelIndex &index);/// 列表视图元素双击事件信号/// \brief ItemElementDbClick/// \param nElement/// \param index///void ItemElementDbClick(const int &nElement,const QModelIndex &index);/// 列表视图Ui元素鼠标悬停事件/// \brief ItemElementHover/// \param nElement           元素索引定义 0:头像区域,1呼叫按钮区域,2发送邮件按钮区域,3发起会话按钮区域,4发送邀请按钮区域,5更多选项按钮区域/// \param index/// \param itemRect           当前项目矩形区域/// \param evtPos             鼠标悬停位置坐标[当前窗口]/// \param evtGlobalPos       鼠标悬停位置坐标[桌面窗口]///void ItemElementHover(const int &nElement,const QModelIndex &index,const QRect &itemRect,const QPoint &evtPos,const QPoint &evtGlobalPos);/// 处理列表项单击信号/// \brief HandItemsClicked/// \param index///void ListItemsClicked(const QModelIndex &index);/// 分组右键单击事件/// \brief GroupsRightClicked/// \param tGroupInf/// \param point///void GroupsRightClicked(const LQNAVLISTVIEW_GROUP &tGroupInf,const QPoint &point,const QModelIndex &index);/// 联系人右键单击事件/// \brief ItemRightClickEvts/// \param tUsersInf/// \param point///void ItemRightClickEvts(const LNCFQCONTACT_LISTVIEWS &tItemsInf,const QPoint &point,const QModelIndex &index);

不知不觉两万多字,实现代码就不提供了,夜深了,以后有时间条件允许并且可行的情况下酌情补上实现代码

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

C++,Qt开发的通讯录列表控件相关推荐

  1. linux qt控件大全,Qt实现复杂的列表控件

    有人问,复杂列表控件怎么做? 控件布局如下图,求指点思路 有高手指点如下, 红框圈起来的是QLabel,1个进度条,2个按钮(toolButton),1个布局,1个QWidget(容器),组成一个wi ...

  2. QT开发及实例学习之六控件

    文章目录 一.按钮组(Buttons) 二.输入部件组(Input Widgets) 1.QDateTime类 2.QTimer类 三.显示控件组(Display Widgets) 1.Text Br ...

  3. 分享下个人一直以来整理维护的C++/Qt开发用到的控件库

    今天分享下个人一直以来在维护的一个C++/Qt开发库,感兴趣的可以关注并下载下看看,应该会用的到,这个库会不定期的进行更新. 工程结构 详细的说明可以到工程文件下查看readme文件. 部分效果展示 ...

  4. Qt的基本控件——列表控件

    列表控件 1.listWIdget QListWidget类列表框控件用来加载并显示多个列表项.QListWidgetItem类就是列表项类 双击可以直接修改,添加多少行,也有属性可以修改字体颜色大小 ...

  5. 【JQuery Mobile移动应用开发实战】JQuery Mobile基础——列表控件的使用

    文章目录 5. 列表控件的使用 5.1 简单的新闻列表 5.2 音乐专辑列表的显示 5.3 更完善的音乐专辑列表 5.4 显示销售的商品列表 5.5 图书销量排名 5.6 简单的电话通讯录 5.7 让 ...

  6. SharePoint2010沙盒解决方案基础开发——关于TreeView树形控件读取列表数据(树形导航)的webpart开发及问题...

    转:http://blog.csdn.net/miragesky2049/article/details/7204882 SharePoint2010沙盒解决方案基础开发--关于TreeView树形控 ...

  7. android tv 开发布局,Android TV开发总结(七)构建一个TV app中的剧集列表控件

    前言:剧集类控件,在TV app中非常常见,今天将介绍构建一个TV app中的剧集列表控件,此控件上传到我的Github:https://github.com/hejunlin2013/Episode ...

  8. SAP UI5 应用开发教程之二十三 - 列表控件的排序 Sort 和分组 Group

    本教程前一步骤,我们已经实现了给列表控件增加的搜索功能. 在搜索框里输入关键字比如 Salad,就能对发票列表进行过滤,仅显示发票模型里 ProductName 字段里包含 Salad 的那些发票行项 ...

  9. QT 显示中文、解决发布乱码、获得系统特定目录、获取文件属性、列表控件、屏幕截图显示保存(定时器)、视频直播、右键菜单

    显示中文 #include <QTextCodec>int main() {QApplication a(argc, argv);QTextCodec::setCodecForLocade ...

最新文章

  1. 简单创建序列和触发器示例
  2. 在LINUX终端和VIM下复制粘贴
  3. Hive _分桶及抽样查询
  4. 人工智能诗歌写作平台_智能写作VS人工写作,Giiso写作机器人解放你的创造力...
  5. Kicad如何导入封装库、符号库(元件库)以及3D模型文件?
  6. 响应式微服务 in java 译 十六 Deploying a Microservice in OpenShift
  7. win10 桌面设置为远程桌面
  8. prometheus监控mysql指标_使用Prometheus监控MySQL状态
  9. latex表格自动换行
  10. ❤️腾讯面试,万字攻略详解, offer到碗里来❤️
  11. ZZULIOJ 1035: 分段函数求值 (Java)
  12. c++之open_cv 图像的载入、显示与输出
  13. 小程序高级电商前端第1周走进Web全栈工程师一----小程序注册、开发工具推荐、《风袖》首页布局详尽分析、Webstorm开发小程序必配配置、mock数据...
  14. 进行拨测的主要目的都有哪些?
  15. C++基础知识(上)
  16. 初学Python之fractions模块下Fraction使用方法
  17. C++调用C的函数,出现 undefined reference to 的解决办法
  18. elementUI:阻止form的enter(回车键)事件
  19. leetcode---1758.生成交替二进制字符串的最少操作数
  20. 熔断器-hystrix使用

热门文章

  1. 在线计算机科学词典,基于Word2Vec的情感词典自动构建与优化-计算机科学.PDF
  2. 计算机识别技术检测交通标志图片大全,交通标志检测与识别技术分析
  3. Soft:软件开发的简介(敏捷开发等6大软件开发模式)、软件测试的简介(单元测试/集成测试/系统测试/验收测试/回归测试、黑白灰功能测试、DEV等四套环境)、运维的简介之详细攻略
  4. 【期末网页设计】基于HTML学生信息管理系统网页项目的设计与实现
  5. 如何在移动端app中应用字体图标icon fonts
  6. 疯狂android讲义笔记-大局观
  7. 快速删除电脑上的大文件
  8. cdo 发送html,asp使用CDO.Message发送邮件详细代码集合
  9. Scrum的三个内置子模式 | 图解敏捷系列
  10. golang 获取当天是周几(两种方法)