要实现如下对话窗口:

先声明一个封装类FeedBackListItem
feedbacklistitem.h

#ifndef FeedBackListItem_H
#define FeedBackListItem_H#define     COLOR_WHITE         Qt::white
#define     ITEM_HEIGHT         40
#define     ITEM_SPACE          5
#define     HeaderBgColor       QColor(219, 238, 252)
#define     HeaderTextColor     QColor(55, 100, 151)
#define     COLOR_BLACK         Qt::black
#define     HEAD_W_H            40
#define     TEACHER_HEAR        QString::fromLocal8Bit("医生")
#define     DAFENQI_HEAD        QString::fromLocal8Bit("达芬奇")enum Orientation{None,Left,Right
};#include <QWidget>
#include <QPainter>
#include <QEvent>
#include <QDateTime>
class FeedBackListItem : public QWidget
{Q_OBJECTpublic:FeedBackListItem(QWidget *parent,QString text,int Ori);~FeedBackListItem();private:QString     m_text;int         m_width;int         m_oritation;QWidget     *m_parent;QSize       getItemSize(int ,int );void        drawBg(QPainter* painter);void        drawItems(QPainter* painter);
signals:void sendItemSize(int,int);
protected:bool eventFilter(QObject *, QEvent *);};#endif // FeedBackListItem_H

在类FeedBackListItem中利用Qpainter 绘制气泡,文本,头像信息

#include "feedbacklistitem.h"FeedBackListItem::FeedBackListItem(QWidget *parent,QString text,int Ori) :QWidget(parent),m_text(text),m_width(0),m_oritation(Ori)
{m_parent = parent;this->installEventFilter(this);
}
bool FeedBackListItem::eventFilter(QObject *obj, QEvent *event)
{if((obj == this)&&(event->type()==QEvent::Paint)){QPainter painter(this);painter.setRenderHints(QPainter::HighQualityAntialiasing|QPainter::Antialiasing);drawBg(&painter);drawItems(&painter);return QWidget::eventFilter(obj,event);}else{return false;}
}//BG COLOR
void FeedBackListItem::drawBg(QPainter *painter)
{painter->save();// painter->setPen(Qt::NoPen);painter->setBrush(COLOR_WHITE);painter->setPen(COLOR_WHITE);painter->drawRect(rect());painter->restore();
}QSize FeedBackListItem::getItemSize(int width,int height)
{return QSize(width,height);
}void FeedBackListItem::drawItems(QPainter *painter)
{// 绘制item区域painter->save();int nItemY = 0;int nWidth = this->width();nWidth = (0 == nWidth % 2) ? nWidth : nWidth + 1;//top YQPointF topLeft(0,nItemY+30);QPointF bottomRight(nWidth,nItemY + ITEM_HEIGHT + ITEM_SPACE);QRectF  ItemRect(topLeft,bottomRight);painter->save();QTransform t;t.translate(ItemRect.center().x(),ItemRect.center().y());//进入样式// t.scale(m_IIVec.at(nIndex).getZoomingFactor(),m_IIVec.at(nIndex).getZoomingFactor());painter->setTransform(t);QPointF rectTopLeft;QPointF rectBottomRight;QRectF textRect(rectTopLeft,rectBottomRight);QFont font("幼圆", 10);painter->setFont(font);QPainterPath path;// 计算文字的宽度QFontMetrics fm(font);int pixelsWide = fm.width(m_text);int pixelsHigh = fm.height();int m_wf = nWidth * 2 / 3;pixelsHigh = pixelsWide < (m_wf*8/9) ?  ITEM_HEIGHT : (((pixelsWide / (nWidth / 2)) + 2) * ITEM_HEIGHT*2/5);pixelsWide = pixelsWide < (m_wf*8/9) ?  pixelsWide  : (m_wf*8/9);if (Right == m_oritation){painter->save();painter->setPen(Qt::NoPen);painter->setBrush(HeaderBgColor);// 绘制边框  头像边框painter->drawRoundedRect(nWidth / 2 - 55, -ITEM_HEIGHT / 2, HEAD_W_H, HEAD_W_H, 2, 2);// 绘制头像painter->setPen(HeaderTextColor);//painter->drawPixmap(nWidth / 2 - 54, -ITEM_HEIGHT / 2 + 1, 48, 48, QPixmap(""));painter->drawText(nWidth / 2 - 54, -ITEM_HEIGHT / 2 + 1, HEAD_W_H, HEAD_W_H,Qt::AlignCenter,TEACHER_HEAR);painter->restore();// 计算右边的宽度xint nX = (nWidth / 2) - 85 - pixelsWide;if (nX < 0) {nX = -pixelsWide - 85 + nWidth / 2;}painter->save();// 计算气泡框textRect = QRectF(nX, -ITEM_HEIGHT / 2, pixelsWide + 20, pixelsHigh);
#if 1// 计算气泡右边的三角   三角内颜色path.addRoundedRect(textRect, 3, 3);    //聊天框弧度path.moveTo(nWidth / 2 - 65, -ITEM_HEIGHT / 2 + 12);path.lineTo(nWidth / 2 - 55, -ITEM_HEIGHT / 2 + 18);path.lineTo(nWidth / 2 - 65, -ITEM_HEIGHT / 2 + 21);painter->setPen(QColor(140, 170, 202));painter->drawPath(path);//painter->fillPath(path,HeaderTextColor);
#elsepainter->drawPixmap(nX + 10, -ITEM_HEIGHT / 2, pixelsWide, pixelsHigh, QPixmap(""));
#endifpainter->restore();painter->setPen(Qt::white);// 重新调整文字区域textRect = QRectF(nX + 10, -ITEM_HEIGHT / 2, pixelsWide, pixelsHigh);}else {// 绘制气泡区域painter->save();textRect = QRectF(-nWidth / 2 + 59, -ITEM_HEIGHT / 2, pixelsWide + 20, pixelsHigh);// 左边三角path.addRoundedRect(textRect, 3, 3);path.moveTo(-nWidth / 2 + 59, -ITEM_HEIGHT / 2 + 12);path.lineTo(-nWidth / 2 + 49, -ITEM_HEIGHT / 2 + 18);path.lineTo(-nWidth / 2 + 59, -ITEM_HEIGHT / 2 + 21);painter->setPen(QColor(140, 170, 202));painter->drawPath(path);painter->restore();// 绘制头像painter->save();painter->setPen(Qt::NoPen);painter->setBrush(HeaderBgColor);QRectF  leftRect(-nWidth / 2 + 5, -ITEM_HEIGHT / 2, HEAD_W_H, HEAD_W_H);painter->drawRect(leftRect);painter->setPen(HeaderTextColor);painter->drawText(leftRect, Qt::AlignCenter,DAFENQI_HEAD);painter->restore();painter->setPen(COLOR_BLACK);// 绘制文字区域textRect = QRectF(-nWidth / 2 + 59 + 10, -ITEM_HEIGHT / 2, pixelsWide, pixelsHigh);}//设置text颜色painter->setPen(Qt::red);painter->drawText(textRect, m_text, Qt::AlignVCenter |Qt::AlignLeft);painter->restore();/// increment nItemY    item高度设置if(pixelsHigh <= HEAD_W_H){pixelsHigh = HEAD_W_H;nItemY += pixelsHigh + ITEM_SPACE;   //head height + ITEMSPACING}else{nItemY += pixelsHigh + ITEM_SPACE;}//QSize(width(),height)emit sendItemSize(width(),pixelsHigh + ITEM_SPACE+30);
}FeedBackListItem::~FeedBackListItem()
{}

声明一个FeedBackUI类,在其中绘制出整体界面以及对item项的调用
feedbackui.h

#ifndef FEEDBACKUI_H
#define FEEDBACKUI_H#define  StrSubmitSuggestion        QString::fromLocal8Bit("提交意见")
#define  StrTextEdtPlaceHoderText   QString::fromLocal8Bit("请在此输入修改意见:")#include "feedbacklistitem.h"
#include "nofocusdelegate.h"
#include <QLabel>
#include <QWidget>
#include <QVBoxLayout>
#include <QPushButton>
#include <QTextEdit>
#include <QStandardItem>
#include <QAbstractItemModel>
#include <QListWidget>
class FeedBackUI : public QWidget
{Q_OBJECTpublic:FeedBackUI(QWidget *parent = 0);~FeedBackUI();private:QVBoxLayout         *m_mainLayout;QPushButton         *m_submitBtn;FeedBackListItem    *feedItem;QListWidget         *m_listWgt;QTextEdit           *m_textEdt;QListWidgetItem     *item;QListWidgetItem     *itemTime;QLabel              *timeLabel;
private:void    initWgt();QSize   setItemSize(int, int);int     wf;int     hf;
protected:void    resizeEvent(QResizeEvent *);
private slots:void    sltBtnSubmitClicked(bool);void    getItemSize(int,int);};#endif // FEEDBACKUI_H

feedbackui.cpp

#include "feedbackui.h"FeedBackUI::FeedBackUI(QWidget *parent): QWidget(parent),wf(1),hf(1)
{initWgt();
}
void FeedBackUI::initWgt()
{this->setMaximumWidth(1200);this->setFixedHeight(777);this->setMinimumWidth(632);// this->setWindowFlags(Qt::FramelessWindowHint);this->setStyleSheet("QListWidget{""border:        1px solid #8AA0B8;""}""QTextEdit{""border-top:    0px solid #8AA0B8;""border-right:  1px solid #8AA0B8;""border-bottom: 1px solid #8AA0B8;""border-left:   1px solid #8AA0B8;""}""QPushButton{""background-color:#3F70AB;""color:white;""border:0px;""}""QPushButton:pressed{""background-color:#214285;""}");m_mainLayout        = new QVBoxLayout(this);m_textEdt           = new QTextEdit(this);m_submitBtn         = new QPushButton(this);m_listWgt           = new QListWidget(this);m_mainLayout        ->addWidget(m_listWgt);m_mainLayout        ->addWidget(m_textEdt);m_textEdt           ->setPlaceholderText(StrTextEdtPlaceHoderText);m_submitBtn         ->setText(StrSubmitSuggestion);m_textEdt           ->setFixedHeight(180*hf);m_mainLayout        ->setContentsMargins(0,0,0,0);m_mainLayout        ->setSpacing(0);m_listWgt   ->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);m_listWgt   ->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);m_listWgt   ->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);//m_listWgt   ->setSelectionMode(QAbstractItemView::NoSelection);//m_listWgt   ->setItemDelegate(new NoFocusDelegate());connect(m_submitBtn,SIGNAL(clicked(bool)),this,SLOT(sltBtnSubmitClicked(bool)));
}void FeedBackUI::sltBtnSubmitClicked(bool)
{// 1 is left    2 is right//m_bubbleList->addItem(m_textEdt->toPlainText(),qrand()%2+1);QString test(m_textEdt->toPlainText());feedItem                = new FeedBackListItem(this,test,qrand()%2+1);QDateTime time = QDateTime::currentDateTime();//获取系统现在的时间QString str = time.toString("yyyy-MM-dd hh:mm:ss"); //设置显示格式timeLabel   = new QLabel(m_listWgt);timeLabel   ->setText(str);timeLabel   ->setFixedHeight(30);timeLabel   ->setAlignment(Qt::AlignCenter);itemTime    = new QListWidgetItem(m_listWgt);item        = new QListWidgetItem(m_listWgt);item->setSizeHint(QSize(this->width() - 10, this->height()));m_listWgt   ->setItemWidget(itemTime,timeLabel);m_listWgt   ->setItemWidget(item,feedItem);m_listWgt   ->scrollToBottom();connect(feedItem,SIGNAL(sendItemSize(int,int)),this,SLOT(getItemSize(int,int)));
}
void FeedBackUI::getItemSize(int w, int h)
{item->setSizeHint(QSize(w,h));
}
void FeedBackUI::resizeEvent(QResizeEvent *)
{QRect rect  = this->rect();m_submitBtn ->setGeometry(rect.right()-77*wf,rect.bottom()-39*hf,68*wf,31*hf);m_listWgt   ->setGeometry(0,0,this->width(),this->height()-m_textEdt->height());
}FeedBackUI::~FeedBackUI()
{}

qrand()%2+1 生成的随机数, 1时生成的对话框在右侧,2时,在左侧。

以上有给listWidget 设置delegate

m_listWgt   ->setItemDelegate(new NoFocusDelegate());

其作用是点击item项隐藏虚线框
具体实现:

#ifndef NOFOCUSDELEGATE_H
#define NOFOCUSDELEGATE_H#include <QPainter>
#include <QStyleOptionViewItem>
#include <QModelIndex>
#include <QStyledItemDelegate>
class NoFocusDelegate:public QStyledItemDelegate
{public:NoFocusDelegate();protected:void paint(QPainter* painter, const QStyleOptionViewItem & option, const QModelIndex &index) const;
};#endif // NOFOCUSDELEGATE_H
#include "nofocusdelegate.h"NoFocusDelegate::NoFocusDelegate()
{}
void NoFocusDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{QStyleOptionViewItem itemOption(option);if (itemOption.state & QStyle::State_HasFocus){itemOption.state = itemOption.state ^ QStyle::State_HasFocus;}QStyledItemDelegate::paint(painter, itemOption, index);
}

Qt软件开发文档14---聊天窗口的实现,对QlistWidget点击item项隐藏虚线框的实现相关推荐

  1. Qt软件开发文档20----Qt语言翻译家

    近日SVN改git,公司大佬手把手教修改代码中语言翻译,为了省事,直接截图了. 首先,从CmakeList开始 CmakeLists.txt添加完成后,编译程序,会在原文件路径下出现name_zh.t ...

  2. python软件开发-如何编写Python软件开发文档(7个技巧)

    开发文档是经常被程序员忽略的工作,有时也会被管理者忽略.这往往是由于在项目生命周期结束的后期缺乏时间,以及人们认为自己不擅长写作,其中一些人确实写不好,但他们中的大多数能够完成一个良好的文档. 在任何 ...

  3. 软件开发文档整理(之)一张示意图 | 清晰明了

      在整个软件开发周期,开发文档是必不可少的资料,它们贯穿于整个开发周期,用来评估计划.规划进度.项目管理.软件测试.软件发布,可以说至关重要.   开发文档必须归档,没有归档的文档作用大打折扣,时效 ...

  4. python开发软件的实例-如何编写Python软件开发文档(7个技巧)

    开发文档是经常被程序员忽略的工作,有时也会被管理者忽略.这往往是由于在项目生命周期结束的后期缺乏时间,以及人们认为自己不擅长写作,其中一些人确实写不好,但他们中的大多数能够完成一个良好的文档. 在任何 ...

  5. python写软件实例-如何编写Python软件开发文档(7个技巧)

    开发文档是经常被程序员忽略的工作,有时也会被管理者忽略.这往往是由于在项目生命周期结束的后期缺乏时间,以及人们认为自己不擅长写作,其中一些人确实写不好,但他们中的大多数能够完成一个良好的文档. 在任何 ...

  6. 软件开发中常见英文缩写和各类软件开发文档的英文缩写

    软件开发中常见英文缩写和各类软件开发文档的英文缩写: 文章复制粘贴来源于:http://blog.sina.com.cn/s/blog_7326867a0100yfdl.html 英文简写 文档名称 ...

  7. 软件开发文档的价值和作用

    现代软件研发理念强调敏捷开发,快速迭代,高效地响应用户的需求变化.可以说,自从有了敏捷方法,有相当一部分程序员长出一口气:终于可以不用写文档了. 那么,事实真的如此吗,文档应不应该写,应该如何编写? ...

  8. 软件开发文档模板 (学习)

    1 可行性研究报告  可行性研究报告的编写目的是:说明该软件开发项目的实现在技术.经济和社会条件方面的可行性:评述为了合理地达到开发目标而可能先择的各种方案:说明论证所选定的方案.  可行性研究报告的 ...

  9. Just enough(刚刚好)的软件开发文档什么样?

    在今年与多个软件开发单位的交流中,补文档的问题多次提到,试图通过本文谈谈文档的价值,如何写刚刚好的文档. 软件开发所需要的文档在传统的瀑布型生命周期下典型的有:开发计划,需求规格说明书,设计书(有分成 ...

最新文章

  1. pandas读写结构化数据(read_csv,read_table, read_excel, read_html, read_sql)
  2. zend 修改默认view路径,添加扩展view
  3. 如何使用新的邮件传输规则和邮件策略
  4. iOS执行时工具-cycript
  5. java几种删除_几种删除Linux目录的方法
  6. Team Foundation Server
  7. eclipse 查看jar包源代码两种方式
  8. 机器学习基石第十三讲笔记
  9. 德保罗大学计算机专业,2020年德保罗大学排名TFE Times美国最佳计算机科学硕士专业排名第75...
  10. Linux【实操篇】—— 进程管理、服务管理、软件包管理(rpm、yum)
  11. 继续当搬运工之人人网移动端架构解析
  12. Asset Pricing:Introduction
  13. 大学android五子棋课程目的,基于安卓开发的五子棋课程设计报告..docx
  14. 408计算机组成原理知识点常考点总结
  15. 11、函数进阶---装饰器
  16. 自己动手做一台linux瘦客户机
  17. Fireworks 制作美式涂鸦文字
  18. Jetson WIFI 驱动安装(intel ax200* or inte 9260* 无线模块)
  19. MRD市场澎湃生长,臻和科技MRD技术受关注
  20. 2018教师计算机考试成绩查询,2018下半年教师资格考试成绩查询入口

热门文章

  1. oracle 11g安装时,先决条件检查项提示environment variable:PATH 失败
  2. 微信jssdk获取收货地址
  3. 橙子05-Mapreduce核心思想与工作过程
  4. Idea中修改servlet模板
  5. IOS CoreText.framework --- 基本用法
  6. 系统架构设计师 2:计算机系统
  7. aws s3 php,在Amazon S3上使用php进行强制下载
  8. 2016福州大学软件工程Beta阶段团队作业成绩汇总
  9. PyQt5 - 双QTimer实现并行输出
  10. 再塑生命的人课件PPT模板