Qt 使用QListView实现简约美观的聊天窗口

今天和大家分享一个使用QListView来展现聊天窗口的历史记录的例子, 因为聊天记录可能会有很多, 所以使用试图-模型的方式更加合理
这是最终效果:
在这里插入图片描述

ChatHistoryModel继承自QAbstractListModel ,
ChatHistoryViewDelegate继承自QStyledItemDelegate,
这个例子最关键的就是在QStyledItemDelegate的sizeHint函数中对每一条消息所需的高度进行计算,其他都很简单
一共五个文件,包含一个UI文件,可以直接编译运行

//Widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include "ChatView.h"
namespace Ui {
   
   
class Widget;
}
class Widget : public QWidget
{
   
   
    Q_OBJECT
public:
    explicit Widget(QWidget *parent = nullptr);
    ~Widget();
private:
    Ui::Widget *ui;
    ChatHistoryModel * mModel;
    ChatHistoryViewDelegate * mDelegate;

public slots:
    void onAppendClicked();
private:
    void drawIcon();
};

#endif // WIDGET_H

//Widget.cpp
#include "Widget.h"
#include "ui_Widget.h"
#include <QApplication>
#include <QPixmap>
#include <QPainter>
int main(int argc, char *argv[])
{
   
   
    QApplication a(argc, argv);
    Widget w;
    w.show();
    return a.exec();
}
Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
   
   
    ui->setupUi(this);
    setWindowTitle(" ");
    drawIcon();
    mModel = new ChatHistoryModel;
    ui->listView->setModel(mModel);
    mDelegate = new ChatHistoryViewDelegate(ui->listView);
    ui->listView->setItemDelegate(mDelegate);
    connect(ui->lineEdit,&QLineEdit::returnPressed,this,&Widget::onAppendClicked);
    resize(600,400);
}
void Widget::onAppendClicked(){
   
   
    auto msg = ui->lineEdit->text().trimmed();
    if(ui->radioButtonRecv->isChecked()) msg = "r" + msg;
    else msg = "s" + msg;
    ui->lineEdit->clear();
    mModel->append(msg);
    ui->listView->scrollToBottom();
}
void Widget::drawIcon(){
   
   
    static const int LEN = 40;
    QPixmap pix(LEN,LEN);
    pix.fill(QColor("transparent"));
    QPainter painter(&pix);
    painter.setRenderHint(QPainter::Antialiasing);
    painter.setPen(Qt::NoPen);
    painter.setBrush(QBrush("lime"));
    QPainterPath pp;
    pp.addEllipse(QPointF(0,0),LEN/2,LEN/2);
    pp.addEllipse(QPointF(0,0),LEN/2-6,LEN/2-6);
    painter.translate(LEN/2,LEN/2);
    painter.drawPath(pp);
    setWindowIcon(QIcon(pix));
}

Widget::~Widget()
{
   
   
    delete ui;
}

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <c
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值