mirror of
https://gitee.com/Zhaoxin59/my-chat_-client.git
synced 2026-02-14 00:51:48 +08:00
320 lines
9.8 KiB
C++
320 lines
9.8 KiB
C++
#include "sessionfriendarea.h"
|
||
|
||
|
||
#include "debug.h"
|
||
#include "model/data.h"
|
||
|
||
SessionFriendArea::SessionFriendArea(QWidget *parent)
|
||
: QScrollArea {parent}
|
||
{
|
||
//设置必要属性
|
||
//设置这个才能有滚动效果
|
||
this->setWidgetResizable(true);
|
||
//设置滚动条相关样式
|
||
// this->verticalScrollBar()->setStyleSheet("QScrollBar:vertical { width: 2px; background-color: rgb(46, 46, 46); }");
|
||
//去除或隐藏水平滚动条
|
||
// this->horizontalScrollBar()->setStyleSheet("QScrollBar:horizontal { height: 0px; }");
|
||
this->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||
this->verticalScrollBar()->setStyleSheet(R"(
|
||
QScrollBar:vertical {
|
||
background-color: rgb(231, 231, 231); /* 滚动条背景透明 */
|
||
width: 6px; /* 默认宽度 */
|
||
margin: 0px 0px 0px 0px; /* 边距清零 */
|
||
}
|
||
QScrollBar::handle:vertical {
|
||
background: #CCCCCC; /* 滑块颜色(浅灰色) */
|
||
min-height: 30px; /* 滑块最小高度 */
|
||
border-radius: 3px; /* 圆角 */
|
||
}
|
||
QScrollBar::handle:vertical:hover {
|
||
background: #999999; /* 悬停时滑块颜色加深 */
|
||
width: 10px; /* 悬停时宽度增大 */
|
||
}
|
||
QScrollBar::handle:vertical:pressed {
|
||
background: #666666; /* 按下时颜色更深 */
|
||
}
|
||
QScrollBar::add-line:vertical,
|
||
QScrollBar::sub-line:vertical {
|
||
height: 0px; /* 隐藏上下箭头按钮 */
|
||
background: none;
|
||
}
|
||
QScrollBar::add-page:vertical,
|
||
QScrollBar::sub-page:vertical {
|
||
background: none; /* 滚动条背景区域透明 */
|
||
}
|
||
)");
|
||
|
||
//去除默认的黑边
|
||
this->setStyleSheet("border: 0px solid transparent;");
|
||
|
||
// 把widget创建出来
|
||
container = new QWidget();
|
||
container->setMinimumWidth(310);
|
||
this->setWidget(container);
|
||
|
||
//给这个widget添加布局管理器方便后续添加元素进去
|
||
QVBoxLayout* layout = new QVBoxLayout();
|
||
layout->setContentsMargins(0, 0, 0, 0);
|
||
layout->setSpacing(0);
|
||
layout->setAlignment(Qt::AlignTop);
|
||
container->setLayout(layout);
|
||
|
||
// //简单测试一下滚动的效果(just for testing...)
|
||
// for(int i = 0; i < 50; i++) {
|
||
// QPushButton* btn = new QPushButton();
|
||
// QString Sbtn = "button: " + QString::number(i);
|
||
// btn->setText(Sbtn);
|
||
// layout->addWidget(btn);
|
||
// }
|
||
|
||
//构造一些临时数据作为界面调试的依据
|
||
|
||
|
||
#if TEST_UI
|
||
QIcon icon(":/resource/image/defaultAv.png");
|
||
for(int i = 0; i < 30; i++) {
|
||
this->addItem(SessionItemType, QString::number(i), icon, "张三" + QString::number(i), "test: last message..." + QString::number(i));
|
||
}
|
||
// LOG() << "hello world!";
|
||
#endif
|
||
}
|
||
|
||
SessionFriendItem::SessionFriendItem(QWidget* owner, const QIcon& avatar, const QString& name, const QString& text)
|
||
:owner(owner)
|
||
{
|
||
this->setFixedHeight(70);
|
||
|
||
this->setStyleSheet("QWidget { background-color: rgb(231, 231, 231); }");
|
||
|
||
|
||
//创建网格布局管理器
|
||
QGridLayout* layout = new QGridLayout();
|
||
layout->setContentsMargins(20, 0, 0, 0);
|
||
// layout->setSpacing(0);
|
||
|
||
layout->setHorizontalSpacing(10);
|
||
layout->setVerticalSpacing(0);
|
||
|
||
this->setLayout(layout);
|
||
|
||
//创建头像
|
||
QPushButton* avatarBtn = new QPushButton();
|
||
avatarBtn->setFixedSize(50, 50);
|
||
avatarBtn->setIconSize(QSize(50, 50));
|
||
avatarBtn->setIcon(avatar);
|
||
avatarBtn->setStyleSheet("QPushButton {border: none;} ");
|
||
avatarBtn->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||
|
||
//创建名字
|
||
QLabel* nameLabel = new QLabel();
|
||
nameLabel->setText(name);
|
||
nameLabel->setStyleSheet("QLabel { font-size: 18px; font-weight: 600; }");
|
||
nameLabel->setFixedHeight(35);
|
||
nameLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
|
||
|
||
//创建消息预览的label
|
||
QLabel* messageLabel = new QLabel();
|
||
messageLabel->setText(text);
|
||
messageLabel->setStyleSheet("QLabel { font-size: 18px; font-weight: 600; }");
|
||
messageLabel->setFixedHeight(35);
|
||
messageLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
|
||
|
||
|
||
//添加到网格布局
|
||
layout->addWidget(avatarBtn, 0, 0, 2, 2);
|
||
layout->addWidget(nameLabel, 0, 2, 1, 8);
|
||
layout->addWidget(messageLabel, 1, 2, 1, 8);
|
||
}
|
||
|
||
void SessionFriendItem::paintEvent(QPaintEvent *event)
|
||
{
|
||
(void) event;
|
||
QStyleOption opt;
|
||
opt.initFrom(this);
|
||
QPainter p(this);
|
||
style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
|
||
}
|
||
|
||
void SessionFriendItem::mousePressEvent(QMouseEvent *event)
|
||
{
|
||
(void) event;
|
||
|
||
select();
|
||
}
|
||
|
||
void SessionFriendItem::enterEvent(QEvent *event)
|
||
{
|
||
(void) event;
|
||
|
||
if(this->selected) {
|
||
return;
|
||
}
|
||
|
||
this->setStyleSheet("QWidget { background-color: rgb(220, 220, 220); }");
|
||
}
|
||
|
||
void SessionFriendItem::leaveEvent(QEvent *event)
|
||
{
|
||
(void) event;
|
||
|
||
if(this->selected) {
|
||
return;
|
||
}
|
||
|
||
this->setStyleSheet("QWidget { background-color: rgb(231, 231, 231); }");
|
||
}
|
||
|
||
void SessionFriendItem::select()
|
||
{
|
||
//遍历其他元素(还原背景色)
|
||
const QObjectList children = this->parentWidget()->children();
|
||
for(QObject* child : children) {
|
||
if(!child->isWidgetType()) {
|
||
continue;
|
||
}
|
||
//说明是widget 那就将child强转为SessionFriendItem
|
||
SessionFriendItem* item = dynamic_cast<SessionFriendItem*>(child);
|
||
if(item->selected) {
|
||
item->selected = false;
|
||
item->setStyleSheet("QWidget { background-color: rgb(231, 231, 231); }");
|
||
}
|
||
}
|
||
//鼠标点击时会触发这个事件
|
||
//点击时修改背景色
|
||
this->setStyleSheet("QWidget { background-color: rgb(210, 210, 210); }");
|
||
this->selected = true;
|
||
|
||
//调用Active
|
||
this->active();
|
||
}
|
||
|
||
void SessionFriendItem::active()
|
||
{
|
||
//父类不写
|
||
//并不需要实现任何逻辑
|
||
}
|
||
|
||
void SessionFriendArea::clear()
|
||
{
|
||
QLayout* layout = container->layout();
|
||
//遍历布局管理器中的所有元素,依次从布局管理器中删除
|
||
for(int i = layout->count() - 1; i >= 0; i--) {
|
||
//takeAt就能够移除对应下标的元素,但还需要释放对象
|
||
QLayoutItem* item = layout->takeAt(i);
|
||
//进行释放
|
||
if(item->widget()) {
|
||
//把这个移除内容的widget进行释放
|
||
delete item->widget();
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
//////////////////////////////////////////////////////////////////////////////////
|
||
//此时这个函数添加的就不是SessionFriendItem了,而是其子类
|
||
//SessionItem FriendItem ApplyItem
|
||
void SessionFriendArea::addItem(ItemType itemType, const QString& id, const QIcon &avatar, const QString &name, const QString &text)
|
||
{
|
||
// //构造一个Item
|
||
// SessionFriendItem* Item = new SessionFriendItem(this, avatar, name, text);
|
||
// //将Item添加到container中
|
||
// container->layout()->addWidget(Item);
|
||
|
||
SessionFriendItem* item = nullptr;
|
||
switch (itemType) {
|
||
case SessionItemType:
|
||
item = new SessionItem(this, id, avatar, name, text);
|
||
break;
|
||
case FriendItemType:
|
||
item = new FriendItem(this, id, avatar, name, text);
|
||
break;
|
||
case ApplyItemType:
|
||
item = new ApplyItem(this, id, avatar, name);
|
||
break;
|
||
default:
|
||
LOG() << "Error ItemType: " << itemType;
|
||
return;
|
||
}
|
||
|
||
container->layout()->addWidget(item);
|
||
}
|
||
|
||
void SessionFriendArea::clickItem(int index)
|
||
{
|
||
if(index < 0 || index > container->layout()->count()) {
|
||
LOG() << "The subscript of the clicked element is out of range... index:" << index;
|
||
return;
|
||
}
|
||
QLayoutItem* layoutItem = container->layout()->itemAt(index);
|
||
if(layoutItem == nullptr || layoutItem->widget() == nullptr) {
|
||
LOG() << "The specified element does not exist... index: " << index;
|
||
return;
|
||
}
|
||
SessionFriendItem* item = dynamic_cast<SessionFriendItem*>(layoutItem->widget());
|
||
item->select();
|
||
}
|
||
|
||
|
||
////////////////////////////////////////
|
||
/// 会话Item的实现
|
||
////////////////////////////////////////
|
||
SessionItem::SessionItem(QWidget *owner, const QString &chatSessionId, const QIcon &avatar,
|
||
const QString &name, const QString &lastmessage)
|
||
:SessionFriendItem(owner, avatar, name, lastmessage), chatSessionId(chatSessionId)
|
||
{
|
||
|
||
}
|
||
|
||
void SessionItem::active()
|
||
{
|
||
//点击之后,要加载会话历史消息的列表
|
||
LOG() << "click SessionItem... chatSessionId: " << chatSessionId;
|
||
}
|
||
|
||
////////////////////////////////////////
|
||
/// 好友Item的实现
|
||
////////////////////////////////////////
|
||
FriendItem::FriendItem(QWidget *owner, const QString &userId, const QIcon &avatar,
|
||
const QString &name, const QString &description)
|
||
:SessionFriendItem(owner, avatar, name, description), userId(userId)
|
||
{
|
||
|
||
}
|
||
|
||
void FriendItem::active()
|
||
{
|
||
//点击之后,要激活对应的会话列元素
|
||
LOG() << "click FriendItem... userId: " << userId;
|
||
}
|
||
|
||
////////////////////////////////////////
|
||
/// 好友申请Item的实现
|
||
////////////////////////////////////////
|
||
ApplyItem::ApplyItem(QWidget *owner, const QString &userId, const QIcon &avatar,
|
||
const QString &name)
|
||
:SessionFriendItem(owner, avatar, name, ""), userId(userId)
|
||
{
|
||
//移除父类的messageLabel
|
||
QGridLayout* layout = dynamic_cast<QGridLayout*>(this->layout());
|
||
layout->removeWidget(messageLabel);
|
||
//要记得释放内存,否则会内存泄露
|
||
// delete messageLabel;
|
||
|
||
//创建两个按钮
|
||
QPushButton* acceptBtn = new QPushButton();
|
||
acceptBtn->setText("同意");
|
||
QPushButton* rejectBtn = new QPushButton();
|
||
rejectBtn->setText("拒绝");
|
||
|
||
//添加到布局管理器中
|
||
layout->addWidget(acceptBtn, 1, 2, 1, 1);
|
||
layout->addWidget(rejectBtn, 1, 3, 1, 1);
|
||
|
||
}
|
||
|
||
void ApplyItem::active()
|
||
{
|
||
//本就不需要实现任何内容
|
||
LOG() << "click ApplyItem... userId: " << userId;
|
||
}
|