当前位置: 首页 > article >正文

【自定义控件】Qt/C++ 双侧聊天对话框控件

1. 项目简介

本项目实现了一个基于 Qt 的双侧对话框控件,用于模拟聊天窗口。支持动态添加文字和图片消息,并实现消息的左右对齐、头像和用户名显示、时间戳显示等功能。用户还可以自定义背景颜色、背景图片、字体样式和字体颜色。可控件提升直接使用

可联系博主获取源码


发布版下载链接(Windows)

下载已编译的 Windows 可执行程序,直接运行即可体验聊天对话框功能。

链接: https://pan.baidu.com/s/1vmroqg5d2dRubdY6f6HOGw?pwd=jkcf 提取码: jkcf

使用说明

  1. 发布版
    • 下载对应平台的发布版,解压后运行可执行文件即可体验聊天功能。
  2. 源码版
    • 下载源码,使用 Qt Creator 或其他支持 Qt 的开发环境打开 .pro 文件进行编译和运行。
    • 开发者可根据需求进行自定义修改和扩展。

示例

文件结构:
├── 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();
}

说明

  1. 主布局为 QVBoxLayout,包含一个 QScrollArea,用于显示所有的聊天消息。
  2. messageLayout 是垂直布局,负责将每条消息按时间顺序添加到滚动区域中。
  3. 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();
}

功能

  1. 创建头像和用户名的垂直布局 avatarLayout
  2. 消息内容(用户名 + 时间戳 + 文本消息)作为单独的垂直布局 vb
  3. 使用 alignment 参数决定消息的左右对齐方式。
  4. 调用 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();
}

功能

  1. addTextMessage 类似,但消息内容部分用图片替代文字。
  2. 图片缩放到指定大小(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);
}

功能

  1. 支持通过 QColor 设置背景颜色。
  2. 支持通过 QPixmap 设置平铺背景图片。
  3. 背景实时更新,灵活适配不同场景。

3.5 滚动到最新消息
void ChatWidget::scrollToBottom() {
    QScrollBar *bar = scrollArea->verticalScrollBar();
    bar->setValue(bar->maximum());
}

功能
确保每次添加新消息后,滚动条自动滚动到底部,用户始终能看到最新消息。


4. 项目特点

  1. 模块化设计
    • 消息添加、样式设置和布局独立实现,方便扩展和维护。
  2. 动态更新
    • 支持动态修改背景、字体、颜色和内容,适应多种使用场景。
  3. 简洁美观
    • 布局简洁,支持换行和内容自适应。

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);


http://www.kler.cn/a/461917.html

相关文章:

  • 第二十六天 RNN在NLP中的应用
  • Python 链接 Pcomm
  • Golang的并发编程实战经验
  • Servlet解析
  • 分布式微服务项目___某污水处理项目
  • 信息学奥赛一本通:1311:【例2.5】求逆序对
  • 探索电商数据:爬取不同平台商品信息的Python实践
  • 基于WOA-CNN-BiLSTM的多步预测模型
  • SpringBoot整合SpringMVC, SpringBoot扩展SpringMVC
  • 鸿蒙工程签名编译和上架
  • 【Linux】信号处理
  • Java重要面试名词整理(十八):Sentinel
  • 【马来西亚博特拉大主办】第五届电网系统与绿色能源国际学术会议(PGSGE 2025)
  • 【gopher的java学习笔记】依赖管理方式对比(go mod maven)
  • java中多线程的一些常见操作
  • Git快速入门(二)·本地仓库·GitHubDesktop的使用
  • 如何使用python清空特定路径下所有文件夹下中的文件,把空文件夹要保留下来
  • 【开源免费】基于Vue和SpringBoot的共享汽车管理系统(附论文)
  • 【ARM】Keil恢复默认设置
  • 低代码开发助力数字化转型的战略价值
  • vue的整理
  • C++中一些常用头文件及其解析
  • 大数据数仓Hive和数据集市、数据治理
  • [羊城杯 2024]hiden
  • IC验证面试常问问题
  • Lua : Coroutine(协程)