1. 效果

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

2. 步骤

  1. 派生 QStyledIemDelegete 得到一个子类:
  1. class CMyListWidgetDelegate : public QStyledItemDelegate
  1. QlistWidget 指定一个 delegate:
  1. ui->listWidget->setItemDelegate(new CMyListWidgetDelegate(ui->listWidget));
  1. QStyledIemDelegete 派生得到的子类,重写 paintsizeHint 两个函数:
    重写这两个函数,目的是自定义 item 的显示:
  1. // 自定义的 item 的内容
  2. virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
  3. //决定单元格的推荐大小
  4. virtual QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;

备注: 如果没有给 QListWidget 设置 delegateQListWidget 也会给自己创建一个默认的 delegate

3. 程序:

  • MyListWidgetDelegate.h:
  1. #ifndef MYLISTWIDGETDELEGATE_H
  2. #define MYLISTWIDGETDELEGATE_H
  3. #include <QStyledItemDelegate>
  4. class CMyListWidgetDelegate : public QStyledItemDelegate
  5. {
  6. Q_OBJECT
  7. public:
  8. CMyListWidgetDelegate(QObject* pParent);
  9. virtual ~CMyListWidgetDelegate();
  10. private:
  11. //决定如何绘图
  12. virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
  13. //决定单元格的推荐大小
  14. virtual QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
  15. };
  16. #endif // MYLISTWIDGETDELEGATE_H
  • MyListWidgetDelegate.cpp:
  1. #include "MyListWidgetDelegate.h"
  2. #include <QPainter>
  3. CMyListWidgetDelegate::CMyListWidgetDelegate(QObject *pParent)
  4. :QStyledItemDelegate(pParent)
  5. {
  6. }
  7. CMyListWidgetDelegate::~CMyListWidgetDelegate()
  8. {
  9. }
  10. void CMyListWidgetDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
  11. {
  12. //QStyledItemDelegate::paint(painter, option, index);
  13. QRect rect = option.rect; // 目标矩形
  14. rect.adjust(2,2,-2,-2); // 缩小一圈,留出空白间隔
  15. // 取得该项对应的数据
  16. QString qstrFileName = index.data(Qt::DisplayRole).toString();
  17. QString qstrRecordPic = index.data(Qt::UserRole+1).toString();
  18. int iFileSize = index.data(Qt::UserRole+2).toInt();
  19. // 状态显示: 若该项被选中
  20. if(option.state & QStyle::State_Selected)
  21. {
  22. painter->setBrush(QColor(0xCC, 0xAA, 0xAA));
  23. painter->drawRoundedRect(rect, 2, 2);
  24. painter->setBrush(Qt::NoBrush);
  25. }
  26. // 图片显示
  27. {
  28. QRect dst = rect;
  29. dst.setRight(rect.left() + 40);
  30. QRect area(0,0,24,24);
  31. area.moveCenter(dst.center());
  32. QPixmap pixmapPic(qstrRecordPic);
  33. painter->drawPixmap(area, pixmapPic);
  34. }
  35. // 文件名显示
  36. {
  37. QRect dst = rect;
  38. dst.setLeft(rect.left() + 40);
  39. dst.setBottom(rect.top() + 20);
  40. painter->drawText(dst, Qt::AlignLeft | Qt::AlignVCenter, qstrFileName);
  41. }
  42. // 文件大小
  43. {
  44. QRect dst = rect;
  45. dst.setLeft(rect.left() + 40);
  46. dst.setTop(rect.top() + 20);
  47. painter->drawText(dst, Qt::AlignLeft | Qt::AlignVCenter, QString::number(iFileSize));
  48. }
  49. }
  50. QSize CMyListWidgetDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
  51. {
  52. //return QStyledItemDelegate::sizeHint(option, index);
  53. QSize size = QStyledItemDelegate::sizeHint(option, index);
  54. size.setHeight(40);
  55. return size;
  56. }
  • MainWidget.h:
  1. #ifndef MAINWIDGET_H
  2. #define MAINWIDGET_H
  3. #include <QWidget>
  4. namespace Ui {
  5. class CMainWidget;
  6. }
  7. class CMainWidget : public QWidget
  8. {
  9. Q_OBJECT
  10. public:
  11. explicit CMainWidget(QWidget *parent = 0);
  12. ~CMainWidget();
  13. private:
  14. Ui::CMainWidget *ui;
  15. void AddItem(const QString& qstrDownloadFileName, const QString& qstrRecordPic, int iFileSize);
  16. };
  17. #endif // MAINWIDGET_H
  • MainWidget.cpp:
  1. #include "MainWidget.h"
  2. #include "ui_MainWidget.h"
  3. #include "MyListWidgetDelegate.h"
  4. CMainWidget::CMainWidget(QWidget *parent) :
  5. QWidget(parent),
  6. ui(new Ui::CMainWidget)
  7. {
  8. ui->setupUi(this);
  9. //添加数据
  10. AddItem("Video1", ":/images/video_1.png", 1024);
  11. AddItem("Video2", ":/images/video_2.png", 2048);
  12. AddItem("Video3", ":/images/video_3.png", 3072);
  13. AddItem("Video4", ":/images/video_4.png", 4096);
  14. AddItem("Video5", ":/images/video_1.png", 5120);
  15. //使用自定义绘图
  16. ui->listWidget->setItemDelegate(new CMyListWidgetDelegate(ui->listWidget));
  17. }
  18. CMainWidget::~CMainWidget()
  19. {
  20. delete ui;
  21. }
  22. void CMainWidget::AddItem(const QString& qstrDownloadFileName, const QString& qstrRecordPic, int iFileSize)
  23. {
  24. QListWidgetItem* pItem = new QListWidgetItem();
  25. if(nullptr != pItem)
  26. {
  27. pItem->setData(Qt::DisplayRole, qstrDownloadFileName);
  28. pItem->setData(Qt::UserRole + 1, qstrRecordPic);
  29. pItem->setData(Qt::UserRole + 2, iFileSize);
  30. ui->listWidget->addItem(pItem);
  31. }
  32. }
  • main.cpp:
  1. #include "MainWidget.h"
  2. #include <QApplication>
  3. int main(int argc, char *argv[])
  4. {
  5. QApplication a(argc, argv);
  6. CMainWidget w;
  7. w.show();
  8. return a.exec();
  9. }

一些其它

  • 添加分隔线Separator
  1. // Separator
  2. {
  3. QRect dst = rect;
  4. dst.setLeft(rect.left() + 15);
  5. dst.setRight(rect.right() - 5);
  6. dst.setY(rect.bottom() - 0.2);
  7. QBrush b;
  8. b.setColor(Qt::gray);
  9. b.setStyle(Qt::SolidPattern);
  10. painter->fillRect(dst, b);
  11. }
  • 如果你搞不清楚你的范围,可以把该区域都填充一个颜色:

这样,你就知道你当前的大小,高低了。

  1. QBrush brush;
  2. brush.setColor(Qt::yellow);
  3. brush.setStyle(Qt::SolidPattern);
  4. painter->setBrush(brush);
  5. painter->drawRect(dst);
  6. painter->setBrush(Qt::NoBrush);