实现微信/QQ聊天消息显示功能

235 篇文章 174 订阅

1.界面效果

2.设计思路

用一个QListWidget来显示消息,一个QTextEdit来编辑消息,2个QPushButton代表2个正着聊天的小哥,点不同的按钮表示不同的人在发消息。

QListWidget添加消息时,实际添加的是一个自定义控件,这个也是核心所在。这个自定义控件要负责计算文字的高度和宽度,以及样式的渲染。我这里实现的自定义控件比较简单,由1个QWidget和1个QLabel构成,QLabel是QWidget的子控件,文本显示在QLabel上。

3.源码展示

ChatDialog.h

#pragma once

#include <QtWidgets/QMainWindow>
#include "ui_ChatDialog.h"

class ChatDialog : public QMainWindow
{
    Q_OBJECT

public:
    ChatDialog(QWidget *parent = Q_NULLPTR);

public slots:
    void ZhangSanSay();
    void LisiSay();

private:
    Ui::ChatDialogClass ui;  
};

ChatDialog.cpp 

#include "ChatDialog.h"
#include "MsgWidget.h"

ChatDialog::ChatDialog(QWidget *parent)
    : QMainWindow(parent)
{
    ui.setupUi(this);
    connect(ui.pushButton,SIGNAL(clicked()),this,SLOT(ZhangSanSay()));
    connect(ui.pushButton_2, SIGNAL(clicked()), this, SLOT(LisiSay()));

}

//张三发消息
void ChatDialog::ZhangSanSay()
{
    MsgWidget *widget = new MsgWidget(ui.listWidget->width(), ui.textEdit->toPlainText()
        , MsgWidget::MSGWIDGET_LEFT, ui.listWidget);
    QListWidgetItem *item = new QListWidgetItem();
    ui.listWidget->addItem(item);
    ui.listWidget->setItemWidget(item, widget);
    item->setSizeHint(QSize(ui.listWidget->width(),widget->height()));
}

//李四发消息
void ChatDialog::LisiSay()
{
    MsgWidget *widget = new MsgWidget(ui.listWidget->width(), ui.textEdit->toPlainText()
        , MsgWidget::MSGWIDGET_RIGHT, ui.listWidget);
    QListWidgetItem *item = new QListWidgetItem();
    ui.listWidget->addItem(item);
    ui.listWidget->setItemWidget(item, widget);
    item->setSizeHint(QSize(ui.listWidget->width(), widget->height()));
}

MsgWidget.h 

#pragma once

#include <QWidget>


class MsgWidget : public QWidget
{
    Q_OBJECT
public:

    //文本对齐方式:控制文本显示在聊天对话框的左边还是右边
    enum MsgAlignment
    {
        MSGWIDGET_LEFT = 0,
        MSGWIDGET_RIGHT = 1
    };

public:
    /*
     int width:设置每条消息所占的宽度-其值应该为整个聊天记录显示区域的宽度
     QString strTxt:消息文本
     MsgAlignment alignment:对齐方式
     QWidget *parent:父控件,可忽略
    */
    MsgWidget(int width,QString strTxt, MsgAlignment alignment, QWidget *parent = NULL);
    ~MsgWidget();

private:
    int m_iMaxWidthPerLine;
};

MsgWidget.cpp 

#include "MsgWidget.h"
#include "QLabel"

MsgWidget::MsgWidget(int width,QString strTxt, MsgAlignment alignment, QWidget *parent)
    : QWidget(parent)
{
    m_iMaxWidthPerLine = 200;

    //用QLable来显示文本
    QLabel *pLabel = new QLabel(strTxt, this);
    QFont myFont("楷体", 15);
    pLabel->setFont(myFont);
    pLabel->setWordWrap(true);

    //计算要发送的消息显示到某个控件上时,此控件所需要的宽度和高度
    QFontMetrics fm(myFont);
    int textWidthInPixels = fm.width(strTxt);
    int textHeightInPixels = fm.height() + 4;
    int iLineNum = textWidthInPixels / m_iMaxWidthPerLine;
    if (textWidthInPixels % m_iMaxWidthPerLine)
    {
        iLineNum += 1;
    }

    int iSetWidth = (textWidthInPixels > m_iMaxWidthPerLine) ?
        m_iMaxWidthPerLine : textWidthInPixels;
    iSetWidth += 4;//略微调整一下宽度,避免最边上的文字显示不全
    int iSetHeight = iLineNum * textHeightInPixels;

    //调整QLabel的大小和位置
    if (MSGWIDGET_RIGHT == alignment)
    {
        pLabel->setGeometry(width - iSetWidth, 2, iSetWidth, iSetHeight);
        pLabel->setStyleSheet("background-color:#73c1fd");
    }
    else
    {
        pLabel->setGeometry(0, 2, iSetWidth, iSetHeight);
        pLabel->setStyleSheet("background-color:#c0cdd6");
    }
    
    //调整个消息界面的大小,这里主要调整了高度,不然连续发送多条消息时,各消息框之间没有空隙
    this->setFixedSize(QSize(width, iSetHeight + 5));
}

MsgWidget::~MsgWidget()
{
}

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Allen Roson

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值