Files
MyChat_Client/choosefrienddialog.cpp

275 lines
10 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "choosefrienddialog.h"
////////////////////////////////////////////////
/// 选择好友窗口中的一个 元素/好友项
////////////////////////////////////////////////
ChooseFriendItem::ChooseFriendItem(ChooseFriendDialog* owner, const QString& userId, const QIcon& avatar, const QString& name, bool checked)
:userId(userId)
{
// 1. 设置控件的基本属性
this->setFixedHeight(50);
this->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
// 2. 设置布局管理器
QHBoxLayout* layout = new QHBoxLayout();
layout->setSpacing(10);
layout->setContentsMargins(20, 0, 20, 0);
this->setLayout(layout);
// 3. 创建复选框
checkBox = new QCheckBox();
checkBox->setChecked(checked);
checkBox->setFixedSize(25, 25);
QString style = "QCheckBox { background-color: transparent; } QCheckBox::indicator { width: 20px; height: 20px; image: url(:/resource/image/unchecked.png);}";
style += "QCheckBox::indicator:checked { image: url(:/resource/image/checked.png);}";
checkBox->setStyleSheet(style);
// 4. 创建头像
avatarBtn = new QPushButton();
avatarBtn->setFixedSize(40, 40);
avatarBtn->setIconSize(QSize(40, 40));
avatarBtn->setIcon(avatar);
// 5. 创建名字
nameLabel = new QLabel();
nameLabel->setText(name);
nameLabel->setStyleSheet("QLabel {background-color: transparent;}");
// 6. 添加上述内容到布局管理器中
layout->addWidget(checkBox);
layout->addWidget(avatarBtn);
layout->addWidget(nameLabel);
// 7. 连接信号槽
connect(checkBox, &QCheckBox::toggled, this, [=](bool checked) {
if (checked) {
// 勾选了复选框, 把当前这个 Item, 添加到右侧的已选择区域
owner->addSelectedFriend(userId, avatar, name);
}
else {
// 取消勾选
owner->deleteSelectedFriend(userId);
}
});
}
void ChooseFriendItem::paintEvent(QPaintEvent* event)
{
//根据鼠标进入的状态,来决定绘制成不同的颜色
QPainter painter(this);
if (isHover) {
//绘制成深色
painter.fillRect(this->rect(), QColor(230, 230, 230));
}
else {
//绘制成浅色
painter.fillRect(this->rect(), QColor(255, 255, 255));
}
}
void ChooseFriendItem::enterEvent(QEnterEvent* event)
{
(void)event;
isHover = true;
//相当于界面更新
this->update();
//this->repaint(); //也可以
}
void ChooseFriendItem::leaveEvent(QEvent* event)
{
(void)event;
isHover = false;
this->update();
}
ChooseFriendDialog::ChooseFriendDialog(QWidget *parent)
: QDialog(parent)
{
// 1. 设置窗口的基本属性
this->setWindowTitle("选择好友");
this->setWindowIcon(QIcon(":/resource/image/logo.png"));
this->setFixedSize(750, 550);
this->setStyleSheet("QDialog { background-color: rgb(255, 255, 255);}");
this->setAttribute(Qt::WA_DeleteOnClose);
// 2. 创建布局管理器
QHBoxLayout* layout = new QHBoxLayout();
layout->setContentsMargins(0, 0, 0, 0);
layout->setSpacing(0);
this->setLayout(layout);
// 3. 针对左侧窗口进行初始化
initLeft(layout);
// 4. 针对右侧窗口进行初始化
initRight(layout);
}
void ChooseFriendDialog::initLeft(QHBoxLayout* layout)
{
// 1. 创建滚动区域
QScrollArea* scrollArea = new QScrollArea();
scrollArea->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
scrollArea->setWidgetResizable(true);
scrollArea->horizontalScrollBar()->setStyleSheet("QScrollBar:horizontal { height: 0px;}");
scrollArea->verticalScrollBar()->setStyleSheet("QScrollBar:vertical { width: 2px; background-color: rgb(255, 255, 255) }");
scrollArea->setStyleSheet("QScrollArea { border:none; }");
layout->addWidget(scrollArea, 1);
// 2. 创建 QWidget 设置到滚动区域中.
totalContainer = new QWidget();
totalContainer->setObjectName("totalContainer");
totalContainer->setStyleSheet("#totalContainer { background-color: rgb(255, 255, 255); }");
scrollArea->setWidget(totalContainer);
// 3. 创建左侧子窗口内部的 垂直布局管理器
QVBoxLayout* vlayout = new QVBoxLayout();
vlayout->setSpacing(0);
vlayout->setContentsMargins(0, 0, 0, 0);
vlayout->setAlignment(Qt::AlignTop);
totalContainer->setLayout(vlayout);
// 还需要进一步的添加 vlayout 内部的元素, 才能看到效果!
// 此处也是先构造测试数据, 后续接入服务器之后, 从服务器拿到真实的好友列表, 再添加真实的数据
#if TEST_UI
QIcon defaultAvatar(":/resource/image/defaultAvatar.png");
for (int i = 0; i < 15; ++i) {
this->addFriend(QString::number(1000 + i), defaultAvatar, "张三" + QString::number(i), false);
}
#endif
}
void ChooseFriendDialog::initRight(QHBoxLayout* layout)
{
// 1. 创建右侧的布局管理器
QGridLayout* gridLayout = new QGridLayout();
gridLayout->setContentsMargins(20, 0, 20, 20);
gridLayout->setSpacing(10);
layout->addLayout(gridLayout, 1);
// 2. 创建 "提示" label
QLabel* tipLabel = new QLabel();
tipLabel->setText("选择联系人");
tipLabel->setFixedHeight(30);
tipLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
tipLabel->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
tipLabel->setStyleSheet("QLabel { font-size: 16px; font-weight: 700}");
// 3. 创建滚动区域
QScrollArea* scrollArea = new QScrollArea();
scrollArea->setWidgetResizable(true);
scrollArea->verticalScrollBar()->setStyleSheet("QScrollBar:vertical { width: 2px; background-color: rgb(255, 255, 255);}");
scrollArea->horizontalScrollBar()->setStyleSheet("QScrollBar:horizontal {height: 0px;}");
scrollArea->setStyleSheet("QScrollArea {border: none;}");
scrollArea->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
// 4. 创建滚动区域中的 QWidget
selectedContainer = new QWidget();
selectedContainer->setObjectName("selectedContainer");
selectedContainer->setStyleSheet("#selectedContainer { background-color: rgb(255, 255, 255); }");
scrollArea->setWidget(selectedContainer);
// 5. 创建 selectedContainer 中的 "垂直布局"
QVBoxLayout* vlayout = new QVBoxLayout();
vlayout->setSpacing(0);
vlayout->setContentsMargins(0, 0, 0, 0);
vlayout->setAlignment(Qt::AlignTop);
selectedContainer->setLayout(vlayout);
// 6. 创建底部按钮
QString style = "QPushButton { color: rgb(7, 191, 96); background-color: rgb(240, 240, 240); border: none; border-radius: 5px;}";
style += "QPushButton:hover { background-color: rgb(220, 220, 220); } QPushButton:pressed { background-color: rgb(200, 200, 200); }";
QPushButton* okBtn = new QPushButton();
okBtn->setFixedHeight(40);
okBtn->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
okBtn->setText("完成");
okBtn->setStyleSheet(style);
QPushButton* cancelBtn = new QPushButton();
cancelBtn->setFixedHeight(40);
cancelBtn->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
cancelBtn->setText("取消");
cancelBtn->setStyleSheet(style);
// 7. 把上述控件添加到布局中
gridLayout->addWidget(tipLabel, 0, 0, 1, 9);
gridLayout->addWidget(scrollArea, 1, 0, 1, 9);
gridLayout->addWidget(okBtn, 2, 1, 1, 3);
gridLayout->addWidget(cancelBtn, 2, 5, 1, 3);
// 构造一些数据用来进行测试界面
#if 0
// 此处的数据通过勾选左侧列表来生成.
QIcon defaultAvatar(":/resource/image/defaultAvatar.png");
for (int i = 0; i < 10; ++i) {
this->addSelectedFriend(QString::number(1000 + i), defaultAvatar, "张三" + QString::number(i));
}
#endif
//// 8. 添加信号槽, 处理 ok 和 cancel 的点击
//connect(okBtn, &QPushButton::clicked, this, &ChooseFriendDialog::clickOkBtn);
//connect(cancelBtn, &QPushButton::clicked, this, [=]() {
// this->close();
// });
}
void ChooseFriendDialog::addFriend(const QString& userId, const QIcon& avatar, const QString& name, bool checked)
{
ChooseFriendItem* item = new ChooseFriendItem(this, userId, avatar, name, checked);
totalContainer->layout()->addWidget(item);
}
void ChooseFriendDialog::addSelectedFriend(const QString& userId, const QIcon& avatar, const QString& name)
{
ChooseFriendItem* item = new ChooseFriendItem(this, userId, avatar, name, true);
selectedContainer->layout()->addWidget(item);
}
void ChooseFriendDialog::deleteSelectedFriend(const QString& userId)
{
//遍历selectedContainer中的所有的Item并对比其userId
QVBoxLayout* vlayout = dynamic_cast<QVBoxLayout*>(selectedContainer->layout());
//由于是要遍历加删除所以,要从后向前进行
for (int i = vlayout->count() - 1; i >= 0; --i) {
auto* item = vlayout->itemAt(i);
if (item == nullptr || item->widget() == nullptr) {
continue;
}
ChooseFriendItem* chooseFriendItem = dynamic_cast<ChooseFriendItem*>(item->widget());
//判定当前的Item的userId是否是要删除的userId
if (chooseFriendItem->getUserId() != userId) {
continue;
}
vlayout->removeWidget(chooseFriendItem);
//会报错!!!
// 要释放对象不是直接delete而是告诉qt让qt在信号槽这一轮
// 执行完成后,自行负责释放
//delete chooseFriendItem;
chooseFriendItem->deleteLater();
}
//再遍历一下左侧的列表把左侧对应的item的checkBox的勾选状态给取消
QVBoxLayout* vlayoutLeft = dynamic_cast<QVBoxLayout*>(totalContainer->layout());
for(int i = 0; i < vlayoutLeft->count(); i++) {
auto* item = vlayoutLeft->itemAt(i);
if (item == nullptr || item->widget() == nullptr) {
continue;
}
ChooseFriendItem* chooseFriendItem = dynamic_cast<ChooseFriendItem*>(item->widget());
if (chooseFriendItem->getUserId() != userId) {
continue;
}
//已找到,取消勾选状态
chooseFriendItem->getCheckBox()->setChecked(false);
}
}