diff --git a/CMakeLists.txt b/CMakeLists.txt index 1e30a74..cba053a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -38,6 +38,8 @@ set(PROJECT_SOURCES userinfowidget.cpp sessiondetailwidget.h sessiondetailwidget.cpp + choosefrienddialog.h + choosefrienddialog.cpp ) if(${QT_VERSION_MAJOR} GREATER_EQUAL 6) diff --git a/choosefrienddialog.cpp b/choosefrienddialog.cpp new file mode 100644 index 0000000..6e5e957 --- /dev/null +++ b/choosefrienddialog.cpp @@ -0,0 +1,233 @@ +#include "choosefrienddialog.h" + + +//////////////////////////////////////////////// +/// 选择好友窗口中的一个 元素/好友项 +//////////////////////////////////////////////// +ChooseFriendItem::ChooseFriendItem(ChooseFriendDialog* owner, const QIcon& avatar, const QString& name, bool checked) +{ + // 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(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(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(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 QIcon& avatar, const QString& name, bool checked) +{ + ChooseFriendItem* item = new ChooseFriendItem(this, avatar, name, checked); + totalContainer->layout()->addWidget(item); +} + +void ChooseFriendDialog::addSelectedFriend(const QIcon& avatar, const QString& name) +{ + ChooseFriendItem* item = new ChooseFriendItem(this, avatar, name, true); + selectedContainer->layout()->addWidget(item); +} diff --git a/choosefrienddialog.h b/choosefrienddialog.h new file mode 100644 index 0000000..2806bf1 --- /dev/null +++ b/choosefrienddialog.h @@ -0,0 +1,55 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "debug.h" + +class ChooseFriendDialog; + +//////////////////////////////////////////////// +/// 选择好友窗口中的一个 元素/好友项 +//////////////////////////////////////////////// +class ChooseFriendItem : public QWidget { + Q_OBJECT +public: + ChooseFriendItem(ChooseFriendDialog* owner, const QIcon& avatar, const QString& name, bool checked); + + void paintEvent(QPaintEvent* event) override; + void enterEvent(QEnterEvent* event) override; + void leaveEvent(QEvent* event) override; + +private: + bool isHover = false; + + QCheckBox* checkBox; + QPushButton* avatarBtn; + QLabel* nameLabel; + ChooseFriendDialog* owner; //记录了哪个QWidget持有这个Item,此处应该是ChooseFriendDialog +}; + +class ChooseFriendDialog : public QDialog +{ + Q_OBJECT + +public: + ChooseFriendDialog(QWidget *parent); + + void initLeft(QHBoxLayout* layout); + void initRight(QHBoxLayout* layout); + + void addFriend(const QIcon& avatar, const QString& name, bool checked); + void addSelectedFriend(const QIcon& avatar, const QString& name); + +private: + QWidget* totalContainer; + QWidget* selectedContainer; +}; + diff --git a/sessiondetailwidget.cpp b/sessiondetailwidget.cpp index 06b25e5..9451b2a 100644 --- a/sessiondetailwidget.cpp +++ b/sessiondetailwidget.cpp @@ -86,11 +86,11 @@ SessionDetailWidget::SessionDetailWidget(QWidget *parent) deleteFriendBtn->setStyleSheet(style); layout->addWidget(deleteFriendBtn, 1, 0, 1, 3); - //// 6. 添加信号槽, 处理点击 "创建群聊" 按钮 - //connect(createGroupBtn->getAvatar(), &QPushButton::clicked, this, [=]() { - // ChooseFriendDialog* chooseFriendDialog = new ChooseFriendDialog(this, userInfo.userId); - // chooseFriendDialog->exec(); - // }); + // 6. 添加信号槽, 处理点击 "创建群聊" 按钮 + connect(createGroupBtn->getAvatar(), &QPushButton::clicked, this, [=]() { + ChooseFriendDialog* chooseFriendDialog = new ChooseFriendDialog(this); + chooseFriendDialog->exec(); + }); //connect(deleteFriendBtn, &QPushButton::clicked, this, &SessionDetailWidget::clickDeleteFriendBtn); diff --git a/sessiondetailwidget.h b/sessiondetailwidget.h index 321b3e9..a2f99b0 100644 --- a/sessiondetailwidget.h +++ b/sessiondetailwidget.h @@ -12,6 +12,7 @@ #include "debug.h" #include "model/data.h" +#include "choosefrienddialog.h" using namespace model; @@ -22,6 +23,10 @@ class AvatarItem : public QWidget { public: AvatarItem(const QIcon& avatar, const QString& name); + QPushButton* getAvatar() { + return avatarBtn; + } + private: QPushButton* avatarBtn; QLabel* nameLabel;