【自定义控件】Qt/C++ 双侧聊天对话框控件
1. 项目简介
本项目实现了一个基于 Qt 的双侧对话框控件,用于模拟聊天窗口。支持动态添加文字和图片消息,并实现消息的左右对齐、头像和用户名显示、时间戳显示等功能。用户还可以自定义背景颜色、背景图片、字体样式和字体颜色。可控件提升直接使用
可联系博主获取源码
发布版下载链接(Windows)
下载已编译的 Windows 可执行程序,直接运行即可体验聊天对话框功能。
链接: https://pan.baidu.com/s/1vmroqg5d2dRubdY6f6HOGw?pwd=jkcf 提取码: jkcf
使用说明
- 发布版:
- 下载对应平台的发布版,解压后运行可执行文件即可体验聊天功能。
- 源码版:
- 下载源码,使用 Qt Creator 或其他支持 Qt 的开发环境打开
.pro
文件进行编译和运行。 - 开发者可根据需求进行自定义修改和扩展。
- 下载源码,使用 Qt Creator 或其他支持 Qt 的开发环境打开
示例
文件结构:
├── ChatWidget.h
├── ChatWidget.cpp
├── main.cpp
├── resources/
│ ├── avatar1.png
│ ├── avatar2.png
│ ├── background.png
│ └── ...
├── chatwidget.pro
└── README.md
如需进一步扩展或功能支持,请联系开发者。 [极客晨风]
如果需要实际上传文件链接,可以告知目标上传平台,我可以进一步帮助生成文件内容!
2. 项目核心功能概述
- 消息添加:支持动态添加文字消息和图片消息。
- 布局控制:消息按左右对齐排布,头像与用户名、消息内容分层显示。
- 时间戳显示:每条消息附带时间戳。
- 背景设置:支持背景颜色和背景图片。
- 字体样式:支持自定义字体和字体颜色。
- 滚动功能:新消息自动滚动到最底部。
3. 核心代码模块解析
3.1 ChatWidget 类
ChatWidget 类是整个项目的核心,负责对话框的布局、消息管理和样式设置。
构造函数
ChatWidget::ChatWidget(QWidget *parent) : QWidget(parent),
backgroundColor(Qt::white),
messageFont(QFont("Arial", 10)),
fontColor(Qt::black) {
// 主布局,用于包裹滚动区域
QVBoxLayout *mainLayout = new QVBoxLayout(this);
// 滚动区域,用于显示聊天内容
scrollArea = new QScrollArea(this);
scrollArea->setWidgetResizable(true);
QWidget *scrollWidget = new QWidget(scrollArea);
messageLayout = new QVBoxLayout(scrollWidget);
messageLayout->setAlignment(Qt::AlignTop);
scrollWidget->setLayout(messageLayout);
scrollArea->setWidget(scrollWidget);
mainLayout->addWidget(scrollArea);
// 初始化背景
updateBackground();
}
说明:
- 主布局为
QVBoxLayout
,包含一个QScrollArea
,用于显示所有的聊天消息。 messageLayout
是垂直布局,负责将每条消息按时间顺序添加到滚动区域中。updateBackground()
初始化背景颜色或背景图片。
3.2 添加文字消息
void ChatWidget::addTextMessage(MessageAlignment alignment, const QString &username, const QPixmap &avatar, const QString &text) {
QHBoxLayout *messageRow = new QHBoxLayout(); // 水平布局,用于头像和消息内容的排列
// 头像和用户名布局
QVBoxLayout *avatarLayout = new QVBoxLayout();
QLabel *avatarLabel = new QLabel();
avatarLabel->setPixmap(avatar.scaled(40, 40, Qt::KeepAspectRatio, Qt::SmoothTransformation));
avatarLabel->setFixedSize(40, 40);
avatarLayout->addWidget(avatarLabel);
avatarLayout->setAlignment(Qt::AlignTop);
QVBoxLayout *vb = new QVBoxLayout();
QLabel *usernameLabel = new QLabel(username);
usernameLabel->setAlignment(alignment == Left ? Qt::AlignLeft : Qt::AlignRight);
usernameLabel->setStyleSheet("font-weight: bold; font-size: 12px;");
QLabel *currtimeLabel = new QLabel(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"));
// 消息内容布局
QLabel *messageLabel = new QLabel(text);
messageLabel->setWordWrap(true);
messageLabel->setStyleSheet(QString("QLabel { padding: 10px; border-radius: 8px; background-color: #f0f0f0; color: %1; }")
.arg(fontColor.name()));
messageLabel->setFont(messageFont);
QHBoxLayout *hb = new QHBoxLayout;
if (alignment == Left) {
hb->addWidget(usernameLabel);
hb->addWidget(currtimeLabel);
} else {
hb->addWidget(currtimeLabel);
hb->addWidget(usernameLabel);
}
vb->addLayout(hb);
vb->addWidget(messageLabel);
if (alignment == Left) {
messageRow->addLayout(avatarLayout);
messageRow->addLayout(vb);
messageRow->addStretch();
} else if (alignment == Right) {
messageRow->addStretch();
messageRow->addLayout(vb);
messageRow->addLayout(avatarLayout);
}
messageLayout->addLayout(messageRow);
scrollToBottom();
}
功能:
- 创建头像和用户名的垂直布局
avatarLayout
。 - 消息内容(用户名 + 时间戳 + 文本消息)作为单独的垂直布局
vb
。 - 使用
alignment
参数决定消息的左右对齐方式。 - 调用
scrollToBottom()
确保滚动条滚动到最新消息。
3.3 添加图片消息
void ChatWidget::addImageMessage(MessageAlignment alignment, const QString &username, const QPixmap &avatar, const QPixmap &image) {
QHBoxLayout *messageRow = new QHBoxLayout(); // 水平布局,用于头像和消息内容的排列
// 头像和用户名布局
QVBoxLayout *avatarLayout = new QVBoxLayout();
QLabel *avatarLabel = new QLabel();
avatarLabel->setPixmap(avatar.scaled(40, 40, Qt::KeepAspectRatio, Qt::SmoothTransformation));
avatarLabel->setFixedSize(40, 40);
avatarLayout->addWidget(avatarLabel);
avatarLayout->setAlignment(Qt::AlignTop);
QVBoxLayout *vb = new QVBoxLayout();
QLabel *usernameLabel = new QLabel(username);
usernameLabel->setAlignment(alignment == Left ? Qt::AlignLeft : Qt::AlignRight);
usernameLabel->setStyleSheet("font-weight: bold; font-size: 12px;");
// 图片内容布局
QLabel *imageLabel = new QLabel();
imageLabel->setPixmap(image.scaled(150, 150, Qt::KeepAspectRatio, Qt::SmoothTransformation));
QLabel *currtimeLabel = new QLabel(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"));
QHBoxLayout *hb = new QHBoxLayout;
if (alignment == Left) {
hb->addWidget(usernameLabel);
hb->addWidget(currtimeLabel);
} else {
hb->addWidget(currtimeLabel);
hb->addWidget(usernameLabel);
}
vb->addLayout(hb);
vb->addWidget(imageLabel);
if (alignment == Left) {
messageRow->addLayout(avatarLayout);
messageRow->addLayout(vb);
messageRow->addStretch();
} else if (alignment == Right) {
messageRow->addStretch();
messageRow->addLayout(vb);
messageRow->addLayout(avatarLayout);
}
messageLayout->addLayout(messageRow);
scrollToBottom();
}
功能:
- 与
addTextMessage
类似,但消息内容部分用图片替代文字。 - 图片缩放到指定大小(150x150),保证布局整齐。
3.4 背景设置
void ChatWidget::setBackgroundColor(const QColor &color) {
backgroundColor = color;
backgroundImage = QPixmap(); // 移除背景图片
updateBackground();
}
void ChatWidget::setBackgroundImage(const QPixmap &pixmap) {
backgroundImage = pixmap;
updateBackground();
}
void ChatWidget::updateBackground() {
QPalette pal = palette();
if (!backgroundImage.isNull()) {
QBrush brush(backgroundImage);
brush.setStyle(Qt::TexturePattern); // 平铺模式
pal.setBrush(QPalette::Window, brush);
} else {
pal.setColor(QPalette::Window, backgroundColor);
}
setPalette(pal);
setAutoFillBackground(true);
}
功能:
- 支持通过
QColor
设置背景颜色。 - 支持通过
QPixmap
设置平铺背景图片。 - 背景实时更新,灵活适配不同场景。
3.5 滚动到最新消息
void ChatWidget::scrollToBottom() {
QScrollBar *bar = scrollArea->verticalScrollBar();
bar->setValue(bar->maximum());
}
功能:
确保每次添加新消息后,滚动条自动滚动到底部,用户始终能看到最新消息。
4. 项目特点
- 模块化设计:
- 消息添加、样式设置和布局独立实现,方便扩展和维护。
- 动态更新:
- 支持动态修改背景、字体、颜色和内容,适应多种使用场景。
- 简洁美观:
- 布局简洁,支持换行和内容自适应。
5. 使用示例
QPixmap leftAvatar(":/path/to/avatar_left.png");
QPixmap rightAvatar(":/path/to/avatar_right.png");
QPixmap image(":/path/to/example_image.png");
chatWidget->addTextMessage(ChatWidget::Left, "对方", leftAvatar, "这是一个左侧文字消息");
chatWidget->addTextMessage(ChatWidget::Right, "自己", rightAvatar, "这是一个右侧文字消息");
chatWidget->addImageMessage(ChatWidget::Left, "对方", leftAvatar, image);
chatWidget->addImageMessage(ChatWidget::Right, "自己", rightAvatar, image);
chatWidget->setBackgroundColor(Qt::lightGray);
chatWidget->setFont(QFont("Arial", 12));
chatWidget->setFontColor(Qt::blue);