QListView 自定义Delegate实现图片列表 绘制Button 根据鼠标状态绘制不同的Button效果 附QListView 样式表

通过自定义代理添加按钮结合setViewMode(QListView::IconMode)实现图片列表效果

先上效果图 

 

 导入图片完整路径,在绘制Item时对路径进行处理,只显示文件名

自定义代理  继承QStyledItemDelegate 
重写关键函数: 

//绘画显示
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override;

//事件处理
bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) override;

现实item文本内容过滤可以在paint事件中自定义绘制,也可以通过重写 displayText 函数实现

本次选用的前者,以下是displayText实现的大概思路

QString displayText(const QVariant &value, const QLocale &locale) const
{
    qDebug()<<"displayText:"<<value;
    QVariant new_value = value;
    QString text = value.toString();
    //自定义item文本内容
    new_value.setValue(getNameFromPath(text));
    //传回父类
    return QStyledItemDelegate::displayText(new_value, locale);
}

关键代码 

void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    if (index.isValid()) {
        //将事件传回父类以便其他内容继续绘制
        QStyledItemDelegate::paint(painter, option, index);
        //以下是自定义绘制内容
        QString txt = index.data(Qt::DisplayRole).toString();
        painter->save();
        //设置抗锯齿绘图
        painter->setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform);
        painter->setFont(QFont("Microsoft YaHei", 10));
        //边框圆角半径
        int border_radius = 0;
        QRectF rect = option.rect;
        QBrush brush = option.backgroundBrush;
        //根据鼠标的不同状态(悬停或者选中)绘制图案,用来遮挡源item的文字内容(图片的完整路径)
        QRect background_rect = QRect(rect.left() + margin, rect.bottom() - focus_height - margin, rect.width() - margin*2, focus_height);
        if (option.state.testFlag(QStyle::State_Selected)) {
            painter->setPen(QPen(QColor("#9e9e9e")));
            painter->setBrush(QColor("#9e9e9e"));
            painter->drawRoundedRect(background_rect,border_radius,border_radius);
            //选中item时的效果
            painter->setPen(Qt::black);
            painter->setBrush(Qt::black);
            painter->drawRoundedRect(QRectF(background_rect.left(), background_rect.bottom() - 2, background_rect.width(), 2)
                                     ,border_radius,border_radius);
        }else if (option.state.testFlag(QStyle::State_MouseOver)) {
            painter->setPen(QPen(QColor("#c4c4c4")));
            painter->setBrush(QColor("#c4c4c4"));
            painter->drawRoundedRect(background_rect,border_radius,border_radius);

        }else{
            painter->setPen(QPen(QColor("#dedede")));
            painter->setBrush(QColor("#dedede"));
            painter->drawRoundedRect(background_rect,border_radius,border_radius);
        }

        //当鼠标移入时绘制按钮
        QRectF rf = QRectF(rect.left() + margin, rect.bottom() - focus_height - margin, rect.width() - margin*2, focus_height);
        if (option.state.testFlag(QStyle::State_MouseOver)) {
            QColor c = QColor(Qt::black);
            c.setAlpha(50);
            painter->setPen(c);
            painter->setBrush(c);
            painter->drawRoundedRect(rf ,border_radius,border_radius);
            //计算绘制区域
            QRect checboxRec = calculate_btn_rect(option.rect);
            int mouseType = index.data(btn_role).toInt();
            if(mouseType == QEvent::MouseButtonPress)
            {
                QPixmap map = pix_btn_press.scaledToWidth(checboxRec.width(), Qt::SmoothTransformation);
                painter->drawPixmap(checboxRec, map);
            }else if (mouseType == QEvent::MouseButtonRelease)
            {
                QPixmap map = pix_btn.scaledToWidth(checboxRec.width(), Qt::SmoothTransformation);
                painter->drawPixmap(checboxRec, map);
            }else{
                QPixmap map = pix_btn.scaledToWidth(checboxRec.width(), Qt::SmoothTransformation);//, Qt::SmoothTransformation
                painter->drawPixmap(checboxRec, map);
            }

        }else{
            painter->restore();
            painter->save();
            //绘制图片名
            QFont font;
            font = option.font;
            font.setPointSize(font.pointSize() - 1);
            painter->setFont(font);
            QRect txtRec(rect.left() + margin, rect.y() + rect.height()/10 * 8,
                         rect.width() - margin * 2 , rect.height()/10 * 2);
            painter->drawText(rf,Qt::AlignHCenter |Qt::AlignVCenter, getNameFromPath(txt));
        }
        painter->restore();
    }
}

QListView样式表

QListView {
	background-color: #ffffff;
    border: none;
}
QListView::item {
    color: #000000;
	background-color:#dedede;
    border: transparent;
	margin-top:6px;
	margin-bottom:6px;
	margin-left:6px;
	margin-right:6px;
}
QListView::item:hover {
    background-color: #c4c4c4;
}
QListView::item:selected {
    border-bottom: 3px solid #000000;
	 background-color: #9e9e9e;
}

  • 9
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值