QListView(仿网易云音乐--本地音乐列表)

1.效果图

请添加图片描述

2.下载链接

QListView(仿网易云本地音乐列表)

3.关键代码

void ListDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    QPixmap *playIcon = nullptr;
    QPixmap *collectionIcon = nullptr;
    QPixmap *commentIcon = nullptr;
    QPixmap *moreIcon = nullptr;
    m_eventType = -1;

    //计算5个区域Rect
    auto [textRects,btnRects] = calculateRectArea(option.rect);
    const bool isHover = option.state.testFlag(QStyle::State_MouseOver);
    const QPoint globalPos = QCursor::pos();
    const QPoint mousePos = m_listView->mapFromGlobal(globalPos);
    Qt::CursorShape cursorShape = Qt::ArrowCursor;
    QString tipText;

    //背景
    if(isHover)
    {
        painter->save();
        painter->setPen(Qt::NoPen);
        painter->setBrush(QBrush(QColor(255,255,255)));
        painter->drawRoundedRect(option.rect,10,10);
        painter->restore();
    }

    //第一列:鼠标hover为播放按钮,否则为序号
    if(isHover)
    {
        if(btnRects[kPlay].contains(mousePos))
        {
            cursorShape = Qt::PointingHandCursor;
            tipText = "播放";
            playIcon = m_iconPixmaps[kPlayHover];
            m_eventType = kPlay;
        }
        else
        {
            playIcon = m_iconPixmaps[kPlayNormal];
        }
    }
    else
    {
        painter->drawText(textRects[kSn],Qt::AlignCenter,QString("%1").arg(index.row(),2,10,QChar('0')));
    }

    //第二列:歌曲名+歌手名
    QString title = index.data(Qt::UserRole).toString();
    painter->drawText(textRects[kTitle],Qt::AlignVCenter,title);
    if(textRects[kTitle].contains(mousePos))
    {
        QStringList strList = title.split("\n");
        if(mousePos.y()<option.rect.center().y()) tipText = strList[0];
        else tipText = strList[1];
    }

    //第三列:隐藏的按钮
    if(isHover)
    {
        collectionIcon = m_iconPixmaps[kCollectionNormal];
        commentIcon = m_iconPixmaps[kCommentNormal];
        moreIcon = m_iconPixmaps[kMoreNormal];
        if(!tipText.isEmpty())
        {
        }
        else if(btnRects[kCollection].contains(mousePos))
        {
            cursorShape = Qt::PointingHandCursor;
            tipText = "收藏";
            collectionIcon = m_iconPixmaps[kCollectionHover];
            m_eventType = kCollection;
        }
        else if(btnRects[kComment].contains(mousePos))
        {
            cursorShape =  Qt::ForbiddenCursor;
            tipText = "评论";
            //commentIcon = m_iconPixmaps[kCommentHover];
            //m_eventType = kComment;
        }
        else if(btnRects[kMore].contains(mousePos))
        {
            cursorShape = Qt::PointingHandCursor;
            tipText = "更多";
            moreIcon = m_iconPixmaps[kMoreHover];
            m_eventType = kMore;
        }
    }

    //第四列:专辑名
    QString album = index.data(Qt::UserRole+1).toString();
    painter->drawText(textRects[kAlbum],Qt::AlignCenter,album);

    //第五列:时长
    QString duration = index.data(Qt::UserRole+2).toString();
    painter->drawText(textRects[kDuration],Qt::AlignCenter,duration);

    //第六列:大小
    QString size = index.data(Qt::UserRole+3).toString();
    painter->drawText(textRects[kSize],Qt::AlignCenter,size);

    //真正的画出按钮
    if(playIcon!=nullptr)       painter->drawPixmap(btnRects[kPlay],*playIcon);
    if(collectionIcon!=nullptr) painter->drawPixmap(btnRects[kCollection],*collectionIcon);
    if(commentIcon!=nullptr)    painter->drawPixmap(btnRects[kComment],*commentIcon);
    if(moreIcon!=nullptr)       painter->drawPixmap(btnRects[kMore],*moreIcon);

    //设置鼠标样式
    QApplication::setOverrideCursor(cursorShape);

    //设置提示文本
    if(tipText.isEmpty()) QToolTip::hideText();
    else QToolTip::showText(globalPos,tipText,m_listView);
}

QSize ListDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{
     return QSize(option.rect.width(),85);
}

bool ListDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index)
{
    if(event->type() == QEvent::MouseMove)
    {
        return true;
    }
    else if(event->type() == QEvent::MouseButtonPress)
    {
        QMouseEvent *me = static_cast<QMouseEvent*>(event);
        if(me->button() == Qt::LeftButton)
        {
            if(m_eventType==kPlay)              emit playBtnClicked(index.row());
            else if(m_eventType==kCollection)   emit collectionBtnClicked(index.row());
            else if(m_eventType==kMore)         emit moreBtnClicked(index.row());
        }
    }
    else if(event->type() == QEvent::MouseButtonDblClick)
    {
        QMouseEvent *me = static_cast<QMouseEvent*>(event);
        if(me->button() == Qt::LeftButton)
        {
            emit playBtnClicked(index.row());
        }
    }
    return QStyledItemDelegate::editorEvent(event,model,option,index);
}

//返回<文本rects,按钮rects>
QPair<QVector<QRect>,QVector<QRect>> ListDelegate::calculateRectArea(const QRect &area) const
{
    QVector<QRect> textRects(kTextCount);
    for(int i =0;i<textRects.size();++i)
    {
        int left = (i==0 ? 0 : textRects[i-1].right()+1);
        int width = 0;
        if(i==kSn)
        {
            width = kTitleWidth;
        }
        else if(i==kTitle)
        {
            width = area.width() - (kTitleWidth + (kSize-kHide+1)*kBaseWidth);
        }
        else
        {
            width = kBaseWidth;
        }
        textRects[i] = QRect(left,area.top(),width,area.height());
    }


    QVector<QRect> btnRects(kBtnCount);
    const int top = (area.height() - kIconSize)/2 + area.top();
    QVector<int> vx(kBtnCount);
    vx[kPlay] = (textRects[kSn].width() - kIconSize)/2 + textRects[kSn].left();
    const int count = (kMore-kCollection+1);
    const int interval = (kBaseWidth-count*kIconSize)/(count+1);
    for(int i =kCollection;i<=kMore;++i)
    {
        if(i==kCollection)
        {
            vx[i] = textRects[kHide].left() + interval;
        }
        else
        {
            vx[i] = vx[i-1] + kIconSize + interval;
        }
    }
    for(int i =0;i<vx.size();++i)
    {
        btnRects[i] = QRect(vx[i],top,kIconSize,kIconSize);
    }
    return qMakePair(textRects,btnRects);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

邺清璇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值