mirror of
https://gitee.com/Zhaoxin59/my-chat_-client.git
synced 2026-02-13 16:41:48 +08:00
update showMessage
This commit is contained in:
@ -61,12 +61,12 @@ void MainWidget::initMainWindow()
|
|||||||
|
|
||||||
|
|
||||||
windowLeft->setFixedWidth(70);
|
windowLeft->setFixedWidth(70);
|
||||||
windowMid->setFixedWidth(820);
|
windowMid->setFixedWidth(320);
|
||||||
windowRight->setMinimumWidth(900);
|
windowRight->setMinimumWidth(900);
|
||||||
|
|
||||||
windowLeft->setStyleSheet("QWidget { background-color: rgb(46, 46, 46); }");
|
windowLeft->setStyleSheet("QWidget { background-color: rgb(46, 46, 46); }");
|
||||||
windowMid->setStyleSheet("QWidget { background-color: rgb(247, 247, 247); }");
|
windowMid->setStyleSheet("QWidget { background-color: rgb(247, 247, 247); }");
|
||||||
windowRight->setStyleSheet("QWidget { background-color: rgb(225, 225, 225); }");
|
windowRight->setStyleSheet("QWidget { background-color: rgb(245, 245, 245); }");
|
||||||
|
|
||||||
layout->addWidget(windowLeft);
|
layout->addWidget(windowLeft);
|
||||||
layout->addWidget(windowMid);
|
layout->addWidget(windowMid);
|
||||||
@ -157,7 +157,7 @@ void MainWidget::initMidWindow()
|
|||||||
layout->addWidget(addFriendBtn, 0 ,3);
|
layout->addWidget(addFriendBtn, 0 ,3);
|
||||||
layout->addWidget(spacer3, 0, 4);
|
layout->addWidget(spacer3, 0, 4);
|
||||||
|
|
||||||
layout->addWidget(spacer4, 1, 0);
|
layout->addWidget(spacer4, 1, 0, 1, 5);
|
||||||
layout->addWidget(sessionFriendArea, 2, 0, 1, 5);
|
layout->addWidget(sessionFriendArea, 2, 0, 1, 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -175,8 +175,8 @@ void MainWidget::initRightWindow()
|
|||||||
titleWidget->setFixedHeight(62);
|
titleWidget->setFixedHeight(62);
|
||||||
titleWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
|
titleWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
|
||||||
titleWidget->setObjectName("titleWidget");
|
titleWidget->setObjectName("titleWidget");
|
||||||
titleWidget->setStyleSheet(R"(#titleWidget { border-bottom: 1px solid rgb(230, 230, 230);
|
titleWidget->setStyleSheet(R"(#titleWidget { border-bottom: 2px solid rgb(231, 231, 231);
|
||||||
border-left: 1px solid rgb(230, 230, 230); }
|
border-left: 1px solid rgb(231, 231, 231); }
|
||||||
)");
|
)");
|
||||||
vlayout->addWidget(titleWidget);
|
vlayout->addWidget(titleWidget);
|
||||||
|
|
||||||
|
|||||||
@ -19,6 +19,55 @@ MessageShowArea::MessageShowArea() {
|
|||||||
layout->setSpacing(0);
|
layout->setSpacing(0);
|
||||||
layout->setContentsMargins(0, 0, 0, 0);
|
layout->setContentsMargins(0, 0, 0, 0);
|
||||||
container->setLayout(layout);
|
container->setLayout(layout);
|
||||||
|
|
||||||
|
// 添加测试数据
|
||||||
|
#if TEST_UI
|
||||||
|
bool k = true;
|
||||||
|
for(int i = 0; i < 30; i++) {
|
||||||
|
model::UserInfo userInfo;
|
||||||
|
userInfo.nickname = "xyz" + QString::number(i);
|
||||||
|
userInfo.avatar = QIcon(":/resource/image/defaultAvatar.png");
|
||||||
|
Message message = Message::makeMessage(model::TEXT_TYPE, "", userInfo, (QString("this is a test message...") + QString::number(i)).toUtf8(), "");
|
||||||
|
k = !k;
|
||||||
|
this->addMessage(k, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
//测试长消息
|
||||||
|
model::UserInfo userInfo;
|
||||||
|
userInfo.nickname = "???";
|
||||||
|
|
||||||
|
const QString s = R"(The starry sky is just a few years ago. And the past may no longer exist,The only thing that remains is light years away, it's just an ethereal phantom.)";
|
||||||
|
|
||||||
|
userInfo.avatar = QIcon(":/resource/image/defaultAvatar.png");
|
||||||
|
Message message = Message::makeMessage(model::TEXT_TYPE, "", userInfo, s.toUtf8(), "");
|
||||||
|
this->addMessage(false, message);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageShowArea::addFrontMessage(bool isLeft, const Message &message)
|
||||||
|
{
|
||||||
|
MessageItem* messageItem = MessageItem::makeMessageItem(isLeft, message);
|
||||||
|
QVBoxLayout* layout = dynamic_cast<QVBoxLayout*>(container->layout());
|
||||||
|
layout->insertWidget(0, messageItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageShowArea::addMessage(bool isLeft, const Message &message)
|
||||||
|
{
|
||||||
|
MessageItem* messageItem = MessageItem::makeMessageItem(isLeft, message);
|
||||||
|
container->layout()->addWidget(messageItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageShowArea::clear()
|
||||||
|
{
|
||||||
|
QLayout* layout = container->layout();
|
||||||
|
//要遍历布局管理器,删除里面的元素
|
||||||
|
for(int i = layout->count() - 1; i >= 0; i--) {
|
||||||
|
QLayoutItem* item = layout->takeAt(i);
|
||||||
|
if(item != nullptr && item->widget() != nullptr) {
|
||||||
|
delete item->widget();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////
|
////////////////////////////////////////////
|
||||||
@ -35,8 +84,8 @@ MessageItem *MessageItem::makeMessageItem(bool isLeft, const Message &message)
|
|||||||
//创建对象和布局管理器
|
//创建对象和布局管理器
|
||||||
MessageItem* messageItem = new MessageItem(isLeft);
|
MessageItem* messageItem = new MessageItem(isLeft);
|
||||||
QGridLayout* layout = new QGridLayout();
|
QGridLayout* layout = new QGridLayout();
|
||||||
layout->setSpacing(0);
|
layout->setSpacing(10);
|
||||||
layout->setContentsMargins(0, 0, 0, 0);
|
layout->setContentsMargins(30, 10, 40, 0);
|
||||||
|
|
||||||
//这个message最低不能低于100
|
//这个message最低不能低于100
|
||||||
messageItem->setMinimumHeight(100);
|
messageItem->setMinimumHeight(100);
|
||||||
@ -48,9 +97,9 @@ MessageItem *MessageItem::makeMessageItem(bool isLeft, const Message &message)
|
|||||||
avatarBtn->setIconSize(QSize(40, 40));
|
avatarBtn->setIconSize(QSize(40, 40));
|
||||||
avatarBtn->setIcon(message.sender.avatar);
|
avatarBtn->setIcon(message.sender.avatar);
|
||||||
if(isLeft) {
|
if(isLeft) {
|
||||||
layout->addWidget(avatarBtn, 0, 0, 2, 1, Qt::AlignTop | Qt::AlignLeft);
|
layout->addWidget(avatarBtn, 0, 0, 2, 1, Qt::AlignCenter | Qt::AlignLeft);
|
||||||
} else {
|
} else {
|
||||||
layout->addWidget(avatarBtn, 0, 1, 2, 1, Qt::AlignTop | Qt::AlignRight);
|
layout->addWidget(avatarBtn, 0, 1, 2, 1, Qt::AlignCenter | Qt::AlignRight);
|
||||||
}
|
}
|
||||||
|
|
||||||
//创建名字和时间
|
//创建名字和时间
|
||||||
@ -65,7 +114,145 @@ MessageItem *MessageItem::makeMessageItem(bool isLeft, const Message &message)
|
|||||||
}
|
}
|
||||||
|
|
||||||
//创建消息体
|
//创建消息体
|
||||||
|
QWidget* contentWidget = nullptr;
|
||||||
|
switch(message.messageType) {
|
||||||
|
case model::TEXT_TYPE:
|
||||||
|
contentWidget = makeTextMessageItem(isLeft, message.content);
|
||||||
|
break;
|
||||||
|
case model::IMAGE_TYPE:
|
||||||
|
contentWidget = makeImageMessageItem();
|
||||||
|
break;
|
||||||
|
case model::FILE_TYPE:
|
||||||
|
contentWidget = makeFileMessageItem();
|
||||||
|
break;
|
||||||
|
case model::SPEECH_TYPE:
|
||||||
|
contentWidget = makeSpeechMessageItem();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LOG() << "error messageType: " << message.messageType;
|
||||||
|
}
|
||||||
|
if(isLeft) {
|
||||||
|
layout->addWidget(contentWidget, 1, 1);
|
||||||
|
} else {
|
||||||
|
layout->addWidget(contentWidget, 1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
return messageItem;
|
return messageItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QWidget *MessageItem::makeTextMessageItem(bool isLeft, const QString &text)
|
||||||
|
{
|
||||||
|
MessageContentLabel* messageContentLabel = new MessageContentLabel(text, isLeft);
|
||||||
|
return messageContentLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget *MessageItem::makeImageMessageItem()
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget *MessageItem::makeFileMessageItem()
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget *MessageItem::makeSpeechMessageItem()
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////
|
||||||
|
/// 创建类表示“文本消息”正文部分
|
||||||
|
////////////////////////////////////////////
|
||||||
|
MessageContentLabel::MessageContentLabel(const QString &text, bool isLeft)
|
||||||
|
:isLeft(isLeft)
|
||||||
|
{
|
||||||
|
this->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||||
|
|
||||||
|
QFont font;
|
||||||
|
font.setFamily("微软雅黑");
|
||||||
|
font.setPixelSize(16);
|
||||||
|
|
||||||
|
this->label = new QLabel(this);
|
||||||
|
this->label->setText(text);
|
||||||
|
this->label->setFont(font);
|
||||||
|
this->label->setAlignment(Qt::AlignCenter | Qt::AlignLeft);
|
||||||
|
this->label->setWordWrap(true);
|
||||||
|
this->label->setStyleSheet("QLabel { padding: 0 10px; line-height: 1.2; background-color: transparent; }");
|
||||||
|
}
|
||||||
|
|
||||||
|
//这个函数会在该控件被显示时,自动的调用到
|
||||||
|
void MessageContentLabel::paintEvent(QPaintEvent *event)
|
||||||
|
{
|
||||||
|
(void) event;
|
||||||
|
|
||||||
|
//获取到父元素的宽度
|
||||||
|
QObject* object = this->parent();
|
||||||
|
if(!object->isWidgetType()) {
|
||||||
|
//说明当前的对象不是QWidget,则不需要进行任何后续的绘制操作
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
QWidget* parent = dynamic_cast<QWidget*>(object);
|
||||||
|
int width = parent->width() * 0.6;
|
||||||
|
|
||||||
|
//计算当前文本,如果单行防止放置需要多宽
|
||||||
|
QFontMetrics metrics(this->label->font());
|
||||||
|
int totalWidth = metrics.horizontalAdvance(this->label->text());
|
||||||
|
|
||||||
|
//计算出此处的行数是多少
|
||||||
|
int rows = (totalWidth / (width - 40)) + 1;
|
||||||
|
if(rows == 1) {
|
||||||
|
//若此时得到的行数只有一行
|
||||||
|
width = totalWidth + 40;
|
||||||
|
}
|
||||||
|
|
||||||
|
//根据行数来确定高度
|
||||||
|
//行数 × 行高(字体高度的 1.2 倍) + 上下内边距(各 10px)
|
||||||
|
int height = rows * (this->label->font().pixelSize() * 1.2 ) + 20;
|
||||||
|
|
||||||
|
//绘制圆角矩形和箭头
|
||||||
|
QPainter painter(this);
|
||||||
|
QPainterPath path;
|
||||||
|
//设置抗锯齿
|
||||||
|
painter.setRenderHint(QPainter::Antialiasing);
|
||||||
|
if(isLeft) {
|
||||||
|
painter.setPen(QPen(QColor(255, 255, 255)));
|
||||||
|
painter.setBrush(QColor(255, 255, 255)); //白色填充
|
||||||
|
|
||||||
|
//绘制圆角矩形
|
||||||
|
painter.drawRoundedRect(10, 0, width, height, 10 ,10);
|
||||||
|
//绘制箭头
|
||||||
|
path.moveTo(10, 15);
|
||||||
|
path.lineTo(0, 20);
|
||||||
|
path.lineTo(10, 25);
|
||||||
|
path.closeSubpath(); //绘制的线形成闭合的多边形,才能进行使用Brush填充颜色
|
||||||
|
painter.drawPath(path);//设置好,调用画笔进行绘制操作
|
||||||
|
|
||||||
|
this->label->setGeometry(10, 0, width, height);
|
||||||
|
} else {
|
||||||
|
painter.setPen(QPen(QColor(137, 217, 97)));
|
||||||
|
painter.setBrush(QColor(137, 217, 97));
|
||||||
|
|
||||||
|
//圆角矩形左侧边的横坐标位置
|
||||||
|
int leftPos = this->width() - width - 10; //10 用来容纳箭头的宽度
|
||||||
|
//圆角矩形右侧边的横坐标位置
|
||||||
|
int rightPos = this->width() - 10;
|
||||||
|
|
||||||
|
//绘制圆角矩形
|
||||||
|
painter.drawRoundedRect(leftPos, 0, width, height, 10, 10);
|
||||||
|
//绘制箭头
|
||||||
|
path.moveTo(rightPos, 15);
|
||||||
|
path.lineTo(rightPos + 10, 20);
|
||||||
|
path.lineTo(rightPos, 25);
|
||||||
|
path.closeSubpath(); //绘制的线形成闭合的多边形,才能进行使用Brush填充颜色
|
||||||
|
painter.drawPath(path);//设置好,调用画笔进行绘制操作
|
||||||
|
|
||||||
|
this->label->setGeometry(leftPos, 0, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
//重新设置父元素的高度,保证父元素足够的高,能够容纳下上述绘制消息的显示区域
|
||||||
|
//注意高度要涵盖之前的名字和时间的label的高度,以及留一点的冗余的空间
|
||||||
|
parent->setFixedHeight(height + 50);
|
||||||
|
}
|
||||||
|
|||||||
@ -7,8 +7,12 @@
|
|||||||
#include <QScrollBar>
|
#include <QScrollBar>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
|
#include <QFontMetrics>
|
||||||
|
#include <QPainter>
|
||||||
|
#include <QPainterPath>
|
||||||
|
|
||||||
#include "model/data.h"
|
#include "model/data.h"
|
||||||
|
#include "debug.h"
|
||||||
|
|
||||||
//.h文件中,不宜使用namespace xxx
|
//.h文件中,不宜使用namespace xxx
|
||||||
using model::Message;
|
using model::Message;
|
||||||
@ -22,6 +26,14 @@ class MessageShowArea : public QScrollArea
|
|||||||
public:
|
public:
|
||||||
MessageShowArea();
|
MessageShowArea();
|
||||||
|
|
||||||
|
//头插
|
||||||
|
void addFrontMessage(bool isLeft, const Message& message);
|
||||||
|
//尾插
|
||||||
|
void addMessage(bool isLeft, const Message& message);
|
||||||
|
|
||||||
|
//清空
|
||||||
|
void clear();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QWidget* container;
|
QWidget* container;
|
||||||
};
|
};
|
||||||
@ -38,8 +50,28 @@ public:
|
|||||||
//通过工厂方法创建MessageItem实例
|
//通过工厂方法创建MessageItem实例
|
||||||
static MessageItem* makeMessageItem(bool isLeft, const Message& message);
|
static MessageItem* makeMessageItem(bool isLeft, const Message& message);
|
||||||
|
|
||||||
|
//添加工厂函数
|
||||||
|
static QWidget* makeTextMessageItem(bool isLeft, const QString& message);
|
||||||
|
static QWidget* makeImageMessageItem();
|
||||||
|
static QWidget* makeFileMessageItem();
|
||||||
|
static QWidget* makeSpeechMessageItem();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool isLeft;
|
bool isLeft;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////
|
||||||
|
/// 创建类表示“文本消息”正文部分
|
||||||
|
////////////////////////////////////////////
|
||||||
|
class MessageContentLabel : public QWidget {
|
||||||
|
public:
|
||||||
|
MessageContentLabel(const QString& text, bool isLeft);
|
||||||
|
|
||||||
|
void paintEvent(QPaintEvent* event) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QLabel* label;
|
||||||
|
bool isLeft;
|
||||||
|
};
|
||||||
|
|
||||||
#endif // MESSAGESHOWAREA_H
|
#endif // MESSAGESHOWAREA_H
|
||||||
|
|||||||
@ -17,7 +17,7 @@ SessionFriendArea::SessionFriendArea(QWidget *parent)
|
|||||||
this->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
this->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||||
this->verticalScrollBar()->setStyleSheet(R"(
|
this->verticalScrollBar()->setStyleSheet(R"(
|
||||||
QScrollBar:vertical {
|
QScrollBar:vertical {
|
||||||
background-color: rgb(231, 231, 231); /* 滚动条背景透明 */
|
background-color: rgb(228, 228, 228); /* 滚动条背景透明 */
|
||||||
width: 6px; /* 默认宽度 */
|
width: 6px; /* 默认宽度 */
|
||||||
margin: 0px 0px 0px 0px; /* 边距清零 */
|
margin: 0px 0px 0px 0px; /* 边距清零 */
|
||||||
}
|
}
|
||||||
@ -84,7 +84,7 @@ SessionFriendItem::SessionFriendItem(QWidget* owner, const QIcon& avatar, const
|
|||||||
{
|
{
|
||||||
this->setFixedHeight(70);
|
this->setFixedHeight(70);
|
||||||
|
|
||||||
this->setStyleSheet("QWidget { background-color: rgb(231, 231, 231); }");
|
this->setStyleSheet("QWidget { background-color: rgb(228, 228, 228); }");
|
||||||
|
|
||||||
|
|
||||||
//创建网格布局管理器
|
//创建网格布局管理器
|
||||||
@ -122,8 +122,8 @@ SessionFriendItem::SessionFriendItem(QWidget* owner, const QIcon& avatar, const
|
|||||||
|
|
||||||
//添加到网格布局
|
//添加到网格布局
|
||||||
layout->addWidget(avatarBtn, 0, 0, 2, 2);
|
layout->addWidget(avatarBtn, 0, 0, 2, 2);
|
||||||
layout->addWidget(nameLabel, 0, 2, 1, 8);
|
layout->addWidget(nameLabel, 0, 2, 1, 25);
|
||||||
layout->addWidget(messageLabel, 1, 2, 1, 8);
|
layout->addWidget(messageLabel, 1, 2, 1, 25);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SessionFriendItem::paintEvent(QPaintEvent *event)
|
void SessionFriendItem::paintEvent(QPaintEvent *event)
|
||||||
@ -150,7 +150,7 @@ void SessionFriendItem::enterEvent(QEvent *event)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->setStyleSheet("QWidget { background-color: rgb(220, 220, 220); }");
|
this->setStyleSheet("QWidget { background-color: rgb(215, 215, 215); }");
|
||||||
}
|
}
|
||||||
|
|
||||||
void SessionFriendItem::leaveEvent(QEvent *event)
|
void SessionFriendItem::leaveEvent(QEvent *event)
|
||||||
@ -161,7 +161,7 @@ void SessionFriendItem::leaveEvent(QEvent *event)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->setStyleSheet("QWidget { background-color: rgb(231, 231, 231); }");
|
this->setStyleSheet("QWidget { background-color: rgb(228, 228, 228); }");
|
||||||
}
|
}
|
||||||
|
|
||||||
void SessionFriendItem::select()
|
void SessionFriendItem::select()
|
||||||
@ -176,12 +176,12 @@ void SessionFriendItem::select()
|
|||||||
SessionFriendItem* item = dynamic_cast<SessionFriendItem*>(child);
|
SessionFriendItem* item = dynamic_cast<SessionFriendItem*>(child);
|
||||||
if(item->selected) {
|
if(item->selected) {
|
||||||
item->selected = false;
|
item->selected = false;
|
||||||
item->setStyleSheet("QWidget { background-color: rgb(231, 231, 231); }");
|
item->setStyleSheet("QWidget { background-color: rgb(228, 228, 228); }");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//鼠标点击时会触发这个事件
|
//鼠标点击时会触发这个事件
|
||||||
//点击时修改背景色
|
//点击时修改背景色
|
||||||
this->setStyleSheet("QWidget { background-color: rgb(210, 210, 210); }");
|
this->setStyleSheet("QWidget { background-color: rgb(196, 196, 196); }");
|
||||||
this->selected = true;
|
this->selected = true;
|
||||||
|
|
||||||
//调用Active
|
//调用Active
|
||||||
|
|||||||
Reference in New Issue
Block a user