前言 要实现的效果类似网易云PC客户端本地音乐页面的效果:
效果图:
实现 QListWidget和QListView都能实现,先说一下两者的区别吧,QListWidget和QListView的主要区别在于QListView是基于Model,而QListWidget是基于Item,QListWidget继承于QListView。也就是说QListWidget插入数据的话我们只能通过 addItem 这个方法来实现,QListView插入数据的话我们是往model里面插入数据,而且我们还可以自定义自己的model,易于扩展,降低了数据冗余,提高了程序的效率。
实现方法大概有这么三种:
如果使用QListWidget的话,我们直接调用 setItemWidget 即可。 void setItemWidget(QListWidgetItem *item, QWidget *widget) QListWidget和QListView都可以通过调用 setIndexWidget 实现。但是该方法只适合做静态数据的显示,不适合做一些插入、更新、删除操作的数据显示。 void QAbstractItemView::setIndexWidget(const QModelIndex &index, QWidget *widget) 我们针对QListView实现自己的ItemDelegate。本文就是采用该种方法,重写ItemDelegate的paint函数。 首先实现自己要显示的数据结构体,需要用到Q_DECLARE_METATYPE宏
#include <QMetaType>
typedef struct { QString iconPath; QString singer; QString songsNb; } MuItemData;
Q_DECLARE_METATYPE(MuItemData) item的大小通过sizeHint函数设置:
QSize MuItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const { Q_UNUSED(index) return QSize(option.rect.width(), 50); } 重写paint函数:
void MuItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { if (index.isValid()) { painter->save(); QVariant var = index.data(Qt::UserRole+1); MuItemData itemData = var.value<MuItemData>();
// item 矩形区域 QRectF rect; rect.setX(option.rect.x()); rect.setY(option.rect.y()); rect.setWidth(option.rect.width()-1); rect.setHeight(option.rect.height()-1);
QPainterPath path; path.moveTo(rect.topRight()); path.lineTo(rect.topLeft()); path.quadTo(rect.topLeft(), rect.topLeft()); path.lineTo(rect.bottomLeft()); path.quadTo(rect.bottomLeft(), rect.bottomLeft()); path.lineTo(rect.bottomRight()); path.quadTo(rect.bottomRight(), rect.bottomRight()); path.lineTo(rect.topRight()); path.quadTo(rect.topRight(), rect.topRight());
// 鼠标悬停或者选中时改变背景色 if (option.state.testFlag(QStyle::State_MouseOver)) { painter->setPen(QPen(QColor("#ebeced"))); painter->setBrush(QColor("#ebeced")); painter->drawPath(path); } if (option.state.testFlag(QStyle::State_Selected)) { painter->setPen(QPen(QColor("#e3e3e5"))); painter->setBrush(QColor("#e3e3e5")); painter->drawPath(path); }
// 绘制图片,歌手,数量位置区域 QRectF iconRect = QRect(rect.left()+5, rect.top()+5, 40, 40); QRectF singerRect = QRect(iconRect.right()+5, iconRect.top(), rect.width()-10-iconRect.width(), 20); QRectF songNbRect = QRect(singerRect.left(), singerRect.bottom()+5, rect.width()-10-iconRect.width(), 20);
painter->drawImage(iconRect, QImage(itemData.iconPath)); painter->setPen(QPen(Qt::black)); painter->setFont(QFont("Microsoft Yahei", 10)); painter->drawText(singerRect, itemData.singer);
painter->setPen(QPen(Qt::gray)); painter->drawText(songNbRect, itemData.songsNb);
painter->restore(); } } 插入数据:
#include <QStandardItemModel> #include <QObject> #include "Widget.h" #include "ui_Widget.h" #include "MuListItemData.h" #include "MuItemDelegate.h"
const QStringList icons = { ":/images/HotDog.jpg", ":/images/li.jpg", ":/images/logo.jpg", ":/images/PACT.jpg", ":/images/yang.jpg", ":/images/zhang.jpg", }; const QStringList singers = { "MC-Hotdog", "李荣浩", "Author", "PACT", "杨千嬅", "张震岳", };
Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget) { ui->setupUi(this);
QStandardItemModel *pModel = new QStandardItemModel(); for (int i=0; i<icons.size(); ++i) { QStandardItem *pItem = new QStandardItem; MuItemData itemData; itemData.singer = singers.at(i); itemData.songsNb = QString::number(i * i) + "首"; itemData.iconPath = icons.at(i); pItem->setData(QVariant::fromValue(itemData), Qt::UserRole+1); pModel->appendRow(pItem); }
MuItemDelegate *pItemDelegate = new MuItemDelegate(this); ui->listView->setItemDelegate(pItemDelegate); ui->listView->setModel(pModel); }
Widget::~Widget() { delete ui; }
代码下载: : https://download.csdn.net/download/a844651990/10798713 GitHub: https://github.com/FlyWM/MuListView --------------------- 作者:FlyWM_ 来源: 原文:https://blog.csdn.net/a844651990/article/details/84324560 版权声明:本文为博主原创文章,转载请附上博文链接!