#ifndef MUITEMDELEGATE_H
#define MUITEMDELEGATE_H
#include <QStyledItemDelegate>
class MuItemDelegate : public QStyledItemDelegate
{
public:
explicit MuItemDelegate(QObject *parent = nullptr);
// painting
void paint(QPainter *painter,
const QStyleOptionViewItem &option, const QModelIndex &index) const override;
QSize sizeHint(const QStyleOptionViewItem &option,
const QModelIndex &index) const override;
bool editorEvent(QEvent *event, QAbstractItemModel *model,
const QStyleOptionViewItem &option, const QModelIndex &index) override;
};
#endif // MUITEMDELEGATE_H
#include <QPainter>
#include <QDebug>
#include "MuItemDelegate.h"
#include "MuListItemData.h"
#include "qcoreevent.h"
#include <QPainterPath>
#include <QCheckBox>
#include <QListView>
#include <QStandardItemModel>
#include <QStyledItemDelegate>
#include <QCheckBox>
#include <QLabel>
#include <QHBoxLayout>
#include <QSpacerItem>
MuItemDelegate::MuItemDelegate(QObject *parent)
: QStyledItemDelegate{parent}
{
lineHeight = 40;
}
void MuItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const {
if (!index.isValid())
{
return;
}
auto getRectParam = [=](){
double icoSize = 18;
MuItemDelegate::MUITEM_PARAM_RECT muitemParamRect;
muitemParamRect.leftRect = QRectF(0, 0, 10, lineHeight);
muitemParamRect.checkBoxRect = QRectF(muitemParamRect.leftRect.topRight().x(), 0, icoSize, icoSize);
muitemParamRect.iconRect = QRectF(muitemParamRect.checkBoxRect.topRight().x(), 0, icoSize, icoSize);
muitemParamRect.titleRect = QRectF(muitemParamRect.iconRect.topRight().x(), 0, lineHeight, lineHeight);
muitemParamRect.eyeIconRect = QRectF(muitemParamRect.titleRect.topRight().x(), 0, icoSize, icoSize);
return muitemParamRect;
};
MuItemDelegate::MUITEM_PARAM_RECT muitemParamRect = getRectParam();
// 创建父 QWidget 以容纳复选框和标签
auto createWidget = [=](){
QHBoxLayout* layout = new QHBoxLayout();
QSpacerItem *leftSpacerItem = new QSpacerItem(muitemParamRect.leftRect.width(), muitemParamRect.leftRect.height(), QSizePolicy::Fixed);
layout->addItem(leftSpacerItem);
// 创建复选框
QCheckBox* checkBox = new QCheckBox();
checkBox->setFixedSize(muitemParamRect.checkBoxRect.size().toSize());
checkBox->setCheckable(true);
checkBox->setChecked(index.data(Qt::CheckStateRole) == Qt::Checked);
layout->addWidget(checkBox);
// 创建第一个 QLabel 用于图标显示
QLabel* iconLabel = new QLabel();
QPixmap icon1 = index.data(Qt::DecorationRole).value<QPixmap>();
iconLabel->setFixedSize(muitemParamRect.iconRect.size().toSize());
iconLabel->setPixmap(icon1);
layout->addWidget(iconLabel);
// 创建第二个 QLabel 用于标题显示
QLabel* titleLabel = new QLabel(index.data(Qt::DisplayRole).toString());
layout->addWidget(titleLabel);
// 创建第三个 QLabel 用于第二个图标显示
QLabel* eyeIcoLabel = new QLabel();
QPixmap icon2 = index.data(Qt::UserRole).value<QPixmap>();
eyeIcoLabel->setPixmap(icon2);
eyeIcoLabel->setFixedSize(muitemParamRect.eyeIconRect.size().toSize());
layout->addWidget(eyeIcoLabel);
// 设置布局属性
layout->setContentsMargins(0 ,0, 0, 0);
layout->setStretch(0, 1);
layout->setStretch(1, 1);
layout->setStretch(2, 1);
layout->setStretch(3, 10);
layout->setStretch(4, 1);
return layout;
};
if(index.isValid())
{
QWidget* itemWidget = new QWidget();
itemWidget->setGeometry(option.rect);
QVBoxLayout* vlayout = new QVBoxLayout(itemWidget);
vlayout->addLayout(createWidget());
itemWidget->setGeometry(option.rect);
painter->end();
QPaintDevice* original_pdev_ptr = painter->device();
painter->begin(original_pdev_ptr);
if (option.state & QStyle::State_Selected) {
painter->fillRect(option.rect, option.palette.highlight());
} else {
painter->fillRect(option.rect, option.palette.background());
}
itemWidget->render(original_pdev_ptr,
QPoint(option.rect.x(), option.rect.y()),
QRegion(0, 0, option.rect.width(), option.rect.height()),
QWidget::RenderFlag::DrawChildren);
delete itemWidget;
}
}
bool MuItemDelegate::editorEvent(QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index)
{
if (event->type() == QEvent::MouseButtonRelease)
{
if (index.data(Qt::CheckStateRole) == Qt::Checked)
{
model->setData(index, Qt::Unchecked, Qt::CheckStateRole);
}
else
{
model->setData(index, Qt::Checked, Qt::CheckStateRole);
}
return true;
}
return QStyledItemDelegate::editorEvent(event, model, option, index);
}
QSize MuItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{
Q_UNUSED(index)
return QSize(0, lineHeight);
}
#ifndef LISTVIEW_H
#define LISTVIEW_H
#include <QWidget>
#include <QStandardItemModel>
#include "MuItemDelegate/muitemdelegate.h"
namespace Ui {
class ListView;
}
class ListView : public QWidget
{
Q_OBJECT
public:
explicit ListView(QWidget *parent = nullptr);
~ListView();
QStandardItemModel *m_model;
MuItemDelegate *customDelegate;
private:
Ui::ListView *ui;
};
#endif // LISTVIEW_H
#include "listview.h"
#include "ui_listview.h"
#include "MuListItemData.h"
#include <QDebug>
ListView::ListView(QWidget *parent) :
QWidget(parent),
ui(new Ui::ListView)
{
ui->setupUi(this);
m_model = new QStandardItemModel();
ui->listView->setModel(m_model);
// 使用自定义委托
customDelegate = new MuItemDelegate(this);
ui->listView->setItemDelegate(customDelegate);
// 添加一些项目到QListView
QStringList stringList;
stringList << "Item 1" << "Item 2" << "Item 3" << "Item 4" << "Item 5"
<< "Item 6" << "Item 7" << "Item 8" << "Item 9" << "Item 10"
<< "Item 11" << "Item 12" << "Item 13" << "Item 14" << "Item 15"
<< "Item 16" << "Item 17" << "Item 18" << "Item 19" << "Item 20";
for (const QString &text : qAsConst(stringList)) {
QStandardItem *item = new QStandardItem(text);
item->setCheckable(true);
item->setCheckState(Qt::Unchecked);
//设置图标和第二个图标(可以根据需要设置)
item->setData(QPixmap(":/images/HotDog.jpg"), Qt::DecorationRole);
item->setData(QPixmap(":/images/li.jpg"), Qt::UserRole);
m_model->appendRow(item);
}
}
ListView::~ListView()
{
delete ui;
}
#include <QApplication>
#include "listview.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
ListView *listView = new ListView();
listView->show();
return a.exec();
}