mirror of
https://gitee.com/Zhaoxin59/my-chat_-client.git
synced 2026-02-13 16:41:48 +08:00
improve ui and add historymessagewidget model
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@ -5,6 +5,7 @@ CMakeLists.txt.user
|
||||
.idea/
|
||||
.vscode/
|
||||
.vs/
|
||||
Android/
|
||||
*.iml
|
||||
*.suo
|
||||
*.vsidx
|
||||
|
||||
@ -18,33 +18,6 @@ else()
|
||||
set(QT_VERSION_MAJOR 6)
|
||||
endif()
|
||||
|
||||
#set(PROJECT_SOURCES
|
||||
# main.cpp
|
||||
# mainwidget.cpp
|
||||
# mainwidget.h
|
||||
# mainwidget.ui
|
||||
# model/data.h
|
||||
# resource.qrc
|
||||
# sessionfriendarea.h
|
||||
# sessionfriendarea.cpp
|
||||
# debug.h
|
||||
# messageshowarea.h
|
||||
# messageshowarea.cpp
|
||||
# messageeditarea.h
|
||||
# messageeditarea.cpp
|
||||
# SelfInfoWidget.h
|
||||
# SelfInfoWidget.cpp
|
||||
# userinfowidget.h
|
||||
# userinfowidget.cpp
|
||||
# sessiondetailwidget.h
|
||||
# sessiondetailwidget.cpp
|
||||
# choosefrienddialog.h
|
||||
# choosefrienddialog.cpp
|
||||
# groupsessiondetailwidget.h
|
||||
# groupsessiondetailwidget.cpp
|
||||
#)
|
||||
|
||||
|
||||
file(GLOB PROJECT_SOURCES
|
||||
model/*.h
|
||||
*.cpp
|
||||
@ -53,14 +26,20 @@ file(GLOB PROJECT_SOURCES
|
||||
*.qrc
|
||||
)
|
||||
|
||||
if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
|
||||
if(ANDROID)
|
||||
# Android 平台:附加 Android 可部署资源
|
||||
qt_add_executable(ClientChat
|
||||
MANUAL_FINALIZATION
|
||||
${PROJECT_SOURCES}
|
||||
)
|
||||
# 指定自定义的 Android 部署目录
|
||||
set_property(TARGET ClientChat APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/android")
|
||||
else()
|
||||
if(ANDROID)
|
||||
add_library(ClientChat SHARED ${PROJECT_SOURCES})
|
||||
if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
|
||||
qt_add_executable(ClientChat
|
||||
MANUAL_FINALIZATION
|
||||
${PROJECT_SOURCES}
|
||||
)
|
||||
else()
|
||||
add_executable(ClientChat ${PROJECT_SOURCES})
|
||||
endif()
|
||||
@ -68,13 +47,12 @@ endif()
|
||||
|
||||
target_link_libraries(ClientChat PRIVATE Qt${QT_VERSION_MAJOR}::Widgets)
|
||||
|
||||
include(GNUInstallDirs)
|
||||
install(TARGETS ClientChat
|
||||
BUNDLE DESTINATION .
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
)
|
||||
|
||||
if(QT_VERSION_MAJOR EQUAL 6)
|
||||
if(${QT_VERSION_MAJOR} EQUAL 6)
|
||||
qt_finalize_executable(ClientChat)
|
||||
endif()
|
||||
|
||||
include(GNUInstallDirs)
|
||||
install(TARGETS ClientChat
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
)
|
||||
|
||||
238
historymessagewidget.cpp
Normal file
238
historymessagewidget.cpp
Normal file
@ -0,0 +1,238 @@
|
||||
#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);
|
||||
|
||||
}
|
||||
58
historymessagewidget.h
Normal file
58
historymessagewidget.h
Normal file
@ -0,0 +1,58 @@
|
||||
#pragma once
|
||||
|
||||
#include <QDialog>
|
||||
#include <QGridLayout>
|
||||
#include <QRadioButton>
|
||||
#include <QLineEdit>
|
||||
#include <QPushButton>
|
||||
#include <QLabel>
|
||||
#include <QDateTimeEdit>
|
||||
#include <QScrollArea>
|
||||
#include <QScrollBar>
|
||||
#include <QFileDialog>
|
||||
|
||||
#include "debug.h"
|
||||
#include "model/data.h"
|
||||
|
||||
using model::Message;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/// 表示一个历史消息元素
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class HistoryItem : public QWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
HistoryItem() {}
|
||||
|
||||
static HistoryItem* makeHistoryItem(const Message& message);
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/// 展示历史消息窗口
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class HistoryMessageWidget : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
HistoryMessageWidget(QWidget *parent);
|
||||
|
||||
//在窗口中添加一个历史消息
|
||||
void addHistoryMessage(const Message& message);
|
||||
|
||||
//清空窗口中所有的历史消息
|
||||
void clear();
|
||||
|
||||
private:
|
||||
void initScrollArea(QGridLayout* layout);
|
||||
|
||||
QRadioButton* keyRadioBtn;
|
||||
QRadioButton* timeRadioBtn;
|
||||
QLineEdit* searchEdit;
|
||||
|
||||
QDateTimeEdit* begTimeEdit;
|
||||
QDateTimeEdit* endTimeEdit;
|
||||
|
||||
//持有所有的历史消息结果的容器对象
|
||||
QWidget* container;
|
||||
};
|
||||
@ -177,6 +177,10 @@ MessageEditArea::MessageEditArea(QWidget *parent)
|
||||
|
||||
vlayout->addWidget(sendTextButton, 0, Qt::AlignRight | Qt::AlignVCenter);
|
||||
|
||||
connect(showHistoryBtn, &QPushButton::clicked, this, [=]() {
|
||||
HistoryMessageWidget* historyMessageWidget = new HistoryMessageWidget(this);
|
||||
historyMessageWidget->exec();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -11,6 +11,8 @@
|
||||
//#include <qpropertyanimation.h>
|
||||
//#include <QEvent>
|
||||
|
||||
#include "historymessagewidget.h"
|
||||
|
||||
//编辑消息的区域
|
||||
class MessageEditArea : public QWidget
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user