今天和大家分享一个使用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