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_OBJECT
public:
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_OBJECT
public:
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);