QQ好友列表的实现(QQ9.0版本样式)--使⽤QTreeView
⽂章结构
最终实现效果
以上是实现的最终样式,⾃⼰电脑上安装的QQ9.0版本,就按这个版本来了。
基本功能
实现的⼀些基本功能总结:
1. 分组展⽰好友列表 ,⼀个组下多个好友;
2. Item上绘制头像、在线状态、个性签名、⽤户名+昵称(依据是否VIP设置成不同颜⾊)、视频通话图标;
3. 头像、在线状态、视频通话图标采⽤svg图标格式
4. hover效果,⿏标移⾄Item不同位置,ToolTip显⽰不同的信息,如⿏标移动⾄头像时提⽰“⿏标移到头像上啦!”,⿏标移到视频通
话按钮上显⽰"视频通话"等,默认显⽰⽤户名+昵称+QQ号。
5. 当⿏标移动到某个好友Item上时,对应Item显⽰视频通话图标。
6. 双击Item事件,打开聊天(仅演⽰捕获事件,进⾏弹窗提⽰事件处理结果);
7. 点击视频通话图标,进⾏视频通话(仅演⽰捕获事件,进⾏弹窗提⽰事件处理结果)
代码主要结构
说明:公共UI库主要是⼀些通⽤的处理,⽐如DelegatePainter类,专门⽤来绘制⽂本、图⽚等,TreeView增加了⼀些⾃定义的事件信号,在此处不⼀⼀赘述,若有需要,可直接拿过去复⽤即可,也可以⾃⼰定义其他信号等。我们的好友列表TreeView是继承此类的。源码路径见⽂章最后。
FriendTree类主要⼯作解析
前提:使⽤上⾯提到的公共Ui库。
下⾯讲解下FriendTree主要做的事情,类头⽂件如下:
#pragma once
#include <QTreeView>
#include "PublicGui/TreeView/TreeView.h"
#include "GlobalDefines.h"
using namespace publicgui;
namespace qqfriendlist
{
class ItemDelegate;
class FriendTree : public TreeView
{
Q_OBJECT
public:
FriendTree(QWidget *parent = Q_NULLPTR);
~FriendTree();
// 赋值传⼊分组/好友结构数据
void setValues(const std::vector<Group>& groups);
private:
void initUi();
void initConnection();
// ⾃定义的hover处理
void onHoverHandle(const QModelIndex& index, int role); // ⾃定义的点击事件处理
void onClickedHandle(const QModelIndex& index, int role); private:
QStandardItemModel* m_model{ nullptr }; // model
ItemDelegate* m_delegate{ nullptr };
};
}
以下四个成员函数
#include "FriendTree.h"
#include "ItemDelegate.h"
#include <QHeaderView>
#include <QTime>
#include <QMessageBox>
#include "GlobalDefines.h"
namespace qqfriendlist
{
FriendTree::FriendTree(QWidget *parent)
: TreeView(parent)
{
initUi();
initConnection();
}
FriendTree::~FriendTree()
{
}
/****************************************!
* @brief 赋值接⼝
* @param [in] const std::vector<Group> & groups
* @return void
****************************************/
void FriendTree::setValues(const std::vector<Group>& groups) {
m_model->clear();
for (const auto& group : groups)
{
// 添加分组
QStandardItem* item = new upName);
item->setEditable(false);
qq用户名item->upName, Qt::ToolTipRole);
item->setData(true, static_cast<int>(CustomRole::IsGroupRole));
m_model->appendRow(item);
for (const auto& contact : actList)
{
// 分组下的联系⼈
QStandardItem* contactItem = new QStandardItem(contact.name);
contactItem->setEditable(false);
contactItem->setData(contact.name, Qt::ToolTipRole);
QVariant value{};
value.setValue(contact);
contactItem->setData(value, static_cast<int>(CustomRole::ContactRole));
item->appendRow(contactItem);
}
}
}
/****************************************!
* @brief 初始化界⾯
* @return void
****************************************/
void FriendTree::initUi()
{
setWindowTitle(QStringLiteral("QQ好友列表"));
// basic init
header()->hide(); // 隐藏表头
setIndentation(0); // 左边距设置为0
setAnimated(true); // 展开时动画
m_model = new QStandardItemModel(this);
setModel(m_model);
m_delegate = new ItemDelegate(this);
setItemDelegate(m_delegate);
}
/****************************************!
* @brief 初始化信号槽链接
* @return void
****************************************/
void FriendTree::initConnection()
{
// 点击事件
connect(this, &QTreeView::clicked, [&](const QModelIndex& index)
{
if (index.data(static_cast<int>(CustomRole::IsGroupRole)).toBool())
{
setExpanded(index, !isExpanded(index)); // 单击展开/收缩列表
}
});
// 双击打开聊天
connect(this, &QTreeView::doubleClicked, [&](const QModelIndex& index)
{
if (!index.data(static_cast<int>(CustomRole::IsGroupRole)).toBool())
{
// 不是分组Item才去处理双击事件
auto info = index.data(static_cast<int>(CustomRole::ContactRole)).value<Contact>(); QMessageBox msgBox;
msgBox.setWindowTitle(QStringLiteral("双击打开聊天"));
msgBox.setText(QStringLiteral("你好,") + info.name + QStringLiteral("。在不?"));
<();
}
});
// 展开时更换左侧的展开图标
connect(this, &QTreeView::expanded, [&](const QModelIndex& index)
{
m_model->itemFromIndex(index)->setData(true, static_cast<int>(CustomRole::IsExpandedRole));
});
// 收起时更换左侧的展开图标
connect(this, &QTreeView::collapsed, [&](const QModelIndex& index)
{
m_model->itemFromIndex(index)->setData(false, static_cast<int>(CustomRole::IsExpandedRole));
});
// ⾃定义hover事件
connect(this, &TreeView::signalHover, this, &FriendTree::onHoverHandle);
// ⾃定义点击事件
connect(this, QOverload<const QModelIndex&, int>::of(&TreeView::signalClicked), this, &FriendTree::onClickedHandle); }
/****************************************!
* @brief hover事件处理
* @param [in] const QModelIndex & index 索引项
* @param [in] int role ⾓⾊
* @return void
****************************************/
void FriendTree::onHoverHandle(const QModelIndex& index, int role)
{
if (index.data(static_cast<int>(CustomRole::IsGroupRole)).toBool())
{
return; // 组的hover事件退出
}
else
{
// 不同区域显⽰不同tooltip
auto info = index.data(static_cast<int>(CustomRole::ContactRole)).value<Contact>();
QString displayName{};
switch (role)
{
case static_cast<int>(CustomRole::PortraitRole) : // 视频通话
{
displayName = QStringLiteral("⿏标移到头像上啦!");
break;
}
case static_cast<int>(CustomRole::VideoRole) : // 视频通话
{
displayName = QStringLiteral("视频通话");
break;
}
case static_cast<int>(CustomRole::SignatureRole) : // 个性签名
{
displayName = info.signature;
break;
}
default:
{
// 默认tooltip显⽰⽤户名称+QQ号
displayName = info.name + "(" + info.nickName + ")" + "(" + info.id + ")";
break;
}
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论