1. 效果
使用 Delegate 自定义 QListWidget 的 item,效果如下

2. 步骤
- 派生
QStyledIemDelegete得到一个子类:
class CMyListWidgetDelegate : public QStyledItemDelegate
- 为
QlistWidget指定一个delegate:
ui->listWidget->setItemDelegate(new CMyListWidgetDelegate(ui->listWidget));
QStyledIemDelegete派生得到的子类,重写paint和sizeHint两个函数:
重写这两个函数,目的是自定义 item 的显示:
// 自定义的 item 的内容virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;//决定单元格的推荐大小virtual QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
备注: 如果没有给 QListWidget 设置 delegate, QListWidget 也会给自己创建一个默认的 delegate
3. 程序:
- MyListWidgetDelegate.h:
#ifndef MYLISTWIDGETDELEGATE_H#define MYLISTWIDGETDELEGATE_H#include <QStyledItemDelegate>class CMyListWidgetDelegate : public QStyledItemDelegate{Q_OBJECTpublic:CMyListWidgetDelegate(QObject* pParent);virtual ~CMyListWidgetDelegate();private://决定如何绘图virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;//决定单元格的推荐大小virtual QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;};#endif // MYLISTWIDGETDELEGATE_H
- MyListWidgetDelegate.cpp:
#include "MyListWidgetDelegate.h"#include <QPainter>CMyListWidgetDelegate::CMyListWidgetDelegate(QObject *pParent):QStyledItemDelegate(pParent){}CMyListWidgetDelegate::~CMyListWidgetDelegate(){}void CMyListWidgetDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const{//QStyledItemDelegate::paint(painter, option, index);QRect rect = option.rect; // 目标矩形rect.adjust(2,2,-2,-2); // 缩小一圈,留出空白间隔// 取得该项对应的数据QString qstrFileName = index.data(Qt::DisplayRole).toString();QString qstrRecordPic = index.data(Qt::UserRole+1).toString();int iFileSize = index.data(Qt::UserRole+2).toInt();// 状态显示: 若该项被选中if(option.state & QStyle::State_Selected){painter->setBrush(QColor(0xCC, 0xAA, 0xAA));painter->drawRoundedRect(rect, 2, 2);painter->setBrush(Qt::NoBrush);}// 图片显示{QRect dst = rect;dst.setRight(rect.left() + 40);QRect area(0,0,24,24);area.moveCenter(dst.center());QPixmap pixmapPic(qstrRecordPic);painter->drawPixmap(area, pixmapPic);}// 文件名显示{QRect dst = rect;dst.setLeft(rect.left() + 40);dst.setBottom(rect.top() + 20);painter->drawText(dst, Qt::AlignLeft | Qt::AlignVCenter, qstrFileName);}// 文件大小{QRect dst = rect;dst.setLeft(rect.left() + 40);dst.setTop(rect.top() + 20);painter->drawText(dst, Qt::AlignLeft | Qt::AlignVCenter, QString::number(iFileSize));}}QSize CMyListWidgetDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const{//return QStyledItemDelegate::sizeHint(option, index);QSize size = QStyledItemDelegate::sizeHint(option, index);size.setHeight(40);return size;}
- MainWidget.h:
#ifndef MAINWIDGET_H#define MAINWIDGET_H#include <QWidget>namespace Ui {class CMainWidget;}class CMainWidget : public QWidget{Q_OBJECTpublic:explicit CMainWidget(QWidget *parent = 0);~CMainWidget();private:Ui::CMainWidget *ui;void AddItem(const QString& qstrDownloadFileName, const QString& qstrRecordPic, int iFileSize);};#endif // MAINWIDGET_H
- MainWidget.cpp:
#include "MainWidget.h"#include "ui_MainWidget.h"#include "MyListWidgetDelegate.h"CMainWidget::CMainWidget(QWidget *parent) :QWidget(parent),ui(new Ui::CMainWidget){ui->setupUi(this);//添加数据AddItem("Video1", ":/images/video_1.png", 1024);AddItem("Video2", ":/images/video_2.png", 2048);AddItem("Video3", ":/images/video_3.png", 3072);AddItem("Video4", ":/images/video_4.png", 4096);AddItem("Video5", ":/images/video_1.png", 5120);//使用自定义绘图ui->listWidget->setItemDelegate(new CMyListWidgetDelegate(ui->listWidget));}CMainWidget::~CMainWidget(){delete ui;}void CMainWidget::AddItem(const QString& qstrDownloadFileName, const QString& qstrRecordPic, int iFileSize){QListWidgetItem* pItem = new QListWidgetItem();if(nullptr != pItem){pItem->setData(Qt::DisplayRole, qstrDownloadFileName);pItem->setData(Qt::UserRole + 1, qstrRecordPic);pItem->setData(Qt::UserRole + 2, iFileSize);ui->listWidget->addItem(pItem);}}
- main.cpp:
#include "MainWidget.h"#include <QApplication>int main(int argc, char *argv[]){QApplication a(argc, argv);CMainWidget w;w.show();return a.exec();}
一些其它
- 添加分隔线Separator
// Separator{QRect dst = rect;dst.setLeft(rect.left() + 15);dst.setRight(rect.right() - 5);dst.setY(rect.bottom() - 0.2);QBrush b;b.setColor(Qt::gray);b.setStyle(Qt::SolidPattern);painter->fillRect(dst, b);}
- 如果你搞不清楚你的范围,可以把该区域都填充一个颜色:
这样,你就知道你当前的大小,高低了。
QBrush brush;brush.setColor(Qt::yellow);brush.setStyle(Qt::SolidPattern);painter->setBrush(brush);painter->drawRect(dst);painter->setBrush(Qt::NoBrush);
