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/
|
.idea/
|
||||||
.vscode/
|
.vscode/
|
||||||
.vs/
|
.vs/
|
||||||
|
Android/
|
||||||
*.iml
|
*.iml
|
||||||
*.suo
|
*.suo
|
||||||
*.vsidx
|
*.vsidx
|
||||||
|
|||||||
@ -18,33 +18,6 @@ else()
|
|||||||
set(QT_VERSION_MAJOR 6)
|
set(QT_VERSION_MAJOR 6)
|
||||||
endif()
|
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
|
file(GLOB PROJECT_SOURCES
|
||||||
model/*.h
|
model/*.h
|
||||||
*.cpp
|
*.cpp
|
||||||
@ -53,14 +26,20 @@ file(GLOB PROJECT_SOURCES
|
|||||||
*.qrc
|
*.qrc
|
||||||
)
|
)
|
||||||
|
|
||||||
if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
|
if(ANDROID)
|
||||||
|
# Android 平台:附加 Android 可部署资源
|
||||||
qt_add_executable(ClientChat
|
qt_add_executable(ClientChat
|
||||||
MANUAL_FINALIZATION
|
MANUAL_FINALIZATION
|
||||||
${PROJECT_SOURCES}
|
${PROJECT_SOURCES}
|
||||||
)
|
)
|
||||||
|
# 指定自定义的 Android 部署目录
|
||||||
|
set_property(TARGET ClientChat APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/android")
|
||||||
else()
|
else()
|
||||||
if(ANDROID)
|
if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
|
||||||
add_library(ClientChat SHARED ${PROJECT_SOURCES})
|
qt_add_executable(ClientChat
|
||||||
|
MANUAL_FINALIZATION
|
||||||
|
${PROJECT_SOURCES}
|
||||||
|
)
|
||||||
else()
|
else()
|
||||||
add_executable(ClientChat ${PROJECT_SOURCES})
|
add_executable(ClientChat ${PROJECT_SOURCES})
|
||||||
endif()
|
endif()
|
||||||
@ -68,13 +47,12 @@ endif()
|
|||||||
|
|
||||||
target_link_libraries(ClientChat PRIVATE Qt${QT_VERSION_MAJOR}::Widgets)
|
target_link_libraries(ClientChat PRIVATE Qt${QT_VERSION_MAJOR}::Widgets)
|
||||||
|
|
||||||
include(GNUInstallDirs)
|
if(${QT_VERSION_MAJOR} EQUAL 6)
|
||||||
install(TARGETS ClientChat
|
|
||||||
BUNDLE DESTINATION .
|
|
||||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
|
||||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
|
||||||
)
|
|
||||||
|
|
||||||
if(QT_VERSION_MAJOR EQUAL 6)
|
|
||||||
qt_finalize_executable(ClientChat)
|
qt_finalize_executable(ClientChat)
|
||||||
endif()
|
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);
|
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 <qpropertyanimation.h>
|
||||||
//#include <QEvent>
|
//#include <QEvent>
|
||||||
|
|
||||||
|
#include "historymessagewidget.h"
|
||||||
|
|
||||||
//编辑消息的区域
|
//编辑消息的区域
|
||||||
class MessageEditArea : public QWidget
|
class MessageEditArea : public QWidget
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user