Files
MyChat_Client/historymessagewidget.cpp

239 lines
8.7 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 "historymessagewidget.h"
//工厂函数
HistoryItem* HistoryItem::makeHistoryItem(const Message& message)
{
// 1. 创建出对象
HistoryItem* item = new HistoryItem();
item->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
// 2. 创建布局
QGridLayout* layout = new QGridLayout();
layout->setVerticalSpacing(0);
layout->setHorizontalSpacing(10);
layout->setContentsMargins(0, 0, 0, 0);
item->setLayout(layout);
// 3. 创建头像
QPushButton* avatarBtn = new QPushButton();
avatarBtn->setFixedSize(40, 40);
avatarBtn->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
avatarBtn->setIconSize(QSize(40, 40));
// 当前消息发送者的头像
avatarBtn->setIcon(message.sender.avatar);
avatarBtn->setStyleSheet("QPushButton { border: none; }");
// 4. 创建昵称和时间
QLabel* nameLabel = new QLabel();
nameLabel->setText(message.sender.nickname + " | " + message.time);
nameLabel->setFixedHeight(20); // 高度设置为头像高度的一半
nameLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
// 5. 消息内容部分
QWidget* contentWidget = nullptr;
if (message.messageType == model::MessageType::TEXT_TYPE) {
// 文本消息
QLabel* label = new QLabel();
label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
label->setWordWrap(true);
label->setText(QString(message.content));
label->adjustSize(); // 设置让 label 能够自动调整大小
contentWidget = label;
}
else if (message.messageType == model::MessageType::IMAGE_TYPE) {
// 图片消息
//contentWidget = new ImageButton(message.fileId, message.content);
}
else if (message.messageType == model::MessageType::FILE_TYPE) {
// 文件消息
//contentWidget = new FileLabel(message.fileId, message.fileName);
}
else if (message.messageType == model::MessageType::SPEECH_TYPE) {
// 语音消息
//contentWidget = new SpeechLabel(message.fileId);
}
else {
LOG() << "错误的消息类型! messageType=" << message.messageType;
}
// 6. 把上述控件添加到布局中
layout->addWidget(avatarBtn, 0, 0, 2, 1);
layout->addWidget(nameLabel, 0, 1, 1, 1);
layout->addWidget(contentWidget, 1, 1, 5, 1);
return item;
}
HistoryMessageWidget::HistoryMessageWidget(QWidget *parent)
: QDialog(parent)
{
// 1. 设置窗口本身属性
this->setFixedSize(600, 600);
this->setWindowTitle("历史消息");
this->setWindowIcon(QIcon(":/resource/image/logo.png"));
this->setStyleSheet("QWidget { background-color: rgb(255, 255, 255); }");
this->setAttribute(Qt::WA_DeleteOnClose);
// 2. 创建布局管理器.
QGridLayout* layout = new QGridLayout();
layout->setSpacing(10);
layout->setContentsMargins(30, 30, 30, 0);
this->setLayout(layout);
// 3. 创建单选按钮
keyRadioBtn = new QRadioButton();
timeRadioBtn = new QRadioButton();
keyRadioBtn->setText("按关键词查询");
timeRadioBtn->setText("按时间查询");
// 默认按照关键词查询
keyRadioBtn->setChecked(true);
layout->addWidget(keyRadioBtn, 0, 0, 1, 2);
layout->addWidget(timeRadioBtn, 0, 2, 1, 2);
// 4. 创建搜索框
searchEdit = new QLineEdit();
searchEdit->setFixedHeight(50);
searchEdit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
searchEdit->setPlaceholderText("要搜索的关键词");
searchEdit->setStyleSheet("QLineEdit { border: none; border-radius: 10px; color: rgb(129, 129, 129); background-color: rgb(240, 240, 240); font-size: 16px; padding-left: 10px; }");
layout->addWidget(searchEdit, 1, 0, 1, 8);
// 5. 创建搜索按钮
QPushButton* searchBtn = new QPushButton();
searchBtn->setFixedSize(50, 50);
searchBtn->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
searchBtn->setIconSize(QSize(30, 30));
searchBtn->setIcon(QIcon(":/resource/image/search.png"));
QString btnStyle = "QPushButton { border: none; background-color: rgb(240, 240, 240); border-radius: 10px; }";
btnStyle += "QPushButton:pressed { background-color: rgb(220, 220, 220); }";
searchBtn->setStyleSheet(btnStyle);
layout->addWidget(searchBtn, 1, 8, 1, 1);
// 6. 创建时间相关的部分控件, 初始情况下要隐藏
QLabel* begTag = new QLabel();
begTag->setText("开始时间");
QLabel* endTag = new QLabel();
endTag->setText("结束时间");
begTimeEdit = new QDateTimeEdit();
endTimeEdit = new QDateTimeEdit();
begTimeEdit->setStyleSheet("QDateTimeEdit { color: rgb(0, 0, 0); } ");
endTimeEdit->setStyleSheet("QDateTimeEdit { color: rgb(0, 0, 0); } ");
// [联调新增]
begTimeEdit->setDisplayFormat("yyyy-MM-dd hh:mm");
endTimeEdit->setDisplayFormat("yyyy-MM-dd hh:mm");
begTimeEdit->setFixedHeight(40);
endTimeEdit->setFixedHeight(40);
begTag->hide();
endTag->hide();
begTimeEdit->hide();
endTimeEdit->hide();
// 7. 创建滚动区域
initScrollArea(layout);
// 8. 设置槽函数
connect(keyRadioBtn, &QRadioButton::clicked, this, [=]() {
// 把时间相关的控件, 隐藏起来
layout->removeWidget(begTag);
layout->removeWidget(begTimeEdit);
layout->removeWidget(endTag);
layout->removeWidget(endTimeEdit);
begTag->hide();
begTimeEdit->hide();
endTag->hide();
endTimeEdit->hide();
// 把关键词搜索框显示加入布局
layout->addWidget(searchEdit, 1, 0, 1, 8);
searchEdit->show();
});
connect(timeRadioBtn, &QRadioButton::clicked, this, [=]() {
// 关键词搜索框隐藏并从布局中删除掉.
layout->removeWidget(searchEdit);
searchEdit->hide();
// 把时间相关的控件, 添加到布局中, 并且进行显示.
layout->addWidget(begTag, 1, 0, 1, 1);
layout->addWidget(begTimeEdit, 1, 1, 1, 3);
layout->addWidget(endTag, 1, 4, 1, 1);
layout->addWidget(endTimeEdit, 1, 5, 1, 3);
begTag->show();
begTimeEdit->show();
endTag->show();
endTimeEdit->show();
});
//connect(searchBtn, &QPushButton::clicked, this, &HistoryMessageWidget::clickSearchBtn);
// 构造测试数据
#if TEST_UI
for (int i = 0; i < 30; ++i) {
// 注意此处代码和前面的差别.
// 前面有个代码, UserInfo 必须要 new 出来才能构造. 当时 Item 对象里, 持有了 const UserInfo& , 不是 new 的话
// 就可能使引用指向的对象失效的.
// 此处后续的代码, 都是按照传值的方式来使用 message 的内容, 不 new 也行.
model::UserInfo sender;
sender.userId = "";
sender.nickname = "张三" + QString::number(i);
sender.avatar = QIcon(":/resource/image/defaultAvatar.png");
sender.description = "";
sender.phone = "18612345678";
Message message = Message::makeMessage(model::MessageType::TEXT_TYPE, "", sender, QString("消息内容" + QString::number(i)).toUtf8(), "");
this->addHistoryMessage(message);
}
#endif
}
void HistoryMessageWidget::addHistoryMessage(const Message& message)
{
HistoryItem* item = HistoryItem::makeHistoryItem(message);
container->layout()->addWidget(item);
}
void HistoryMessageWidget::clear()
{
QVBoxLayout* layout = dynamic_cast<QVBoxLayout*>(container->layout());
for (int i = layout->count() - 1; i >= 0; i--) {
//之前使用的是takeat效果和这个是一样的
QWidget* w = layout->itemAt(i)->widget();
if (w == nullptr) {
continue;
}
layout->removeWidget(w);
w->deleteLater();
}
}
void HistoryMessageWidget::initScrollArea(QGridLayout* layout)
{
// 1. 创建滚动区域对象
QScrollArea* scrollArea = new QScrollArea();
scrollArea->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
scrollArea->setWidgetResizable(true);
scrollArea->verticalScrollBar()->setStyleSheet("QScrollBar:vertical { width: 2px; background-color: rgb(255, 255, 255); }");
scrollArea->horizontalScrollBar()->setStyleSheet("QScrollBar:horizontal { height: 0; }");
scrollArea->setStyleSheet("QScrollArea { border: none; }");
// 2. 创建 QWidget, 持有要加入的新的内容
container = new QWidget();
scrollArea->setWidget(container);
// 3. 创建 container 中的布局管理器.
QVBoxLayout* vlayout = new QVBoxLayout();
vlayout->setSpacing(10);
vlayout->setContentsMargins(0, 0, 0, 0);
vlayout->setAlignment(Qt::AlignTop);
container->setLayout(vlayout);
// 4. 把滚动区加入到整个 layout 中
layout->addWidget(scrollArea, 2, 0, 1, 9);
}