注册 登录  
 加关注
查看详情
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

沙漠里de烟雨

原创分享,禁止转载

 
 
 

日志

 
 

Qt之 自定义展开/收起按钮  

2018-04-29 04:23:07|  分类: QT5.x与QML |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
先看效果:
Qt之 自定义展开/收起按钮 - 漠雨 - 沙漠里de烟雨
 
Qt之 自定义展开/收起按钮 - 漠雨 - 沙漠里de烟雨
 
Qt之 自定义展开/收起按钮 - 漠雨 - 沙漠里de烟雨
 
Qt之 自定义展开/收起按钮 - 漠雨 - 沙漠里de烟雨
 

代码如: 
ArrowLabel.h ==== >
#ifndef ARROWLABEL_H
#define ARROWLABEL_H
#include <QLabel>
class QTimer;
class ArrowLabel : public QLabel
{
    Q_OBJECT
public:
    ArrowLabel(bool up, QWidget* parent = 0);

    /* @setArrowAlignment:
    * flag只支持: Qt::AlignLeft,Qt::AlignRight,AlignTop,AlignBottom以及Qt::AlignCenter;
    * 而若Qt::AlignCenter时,鼠标hover上时,文字不显示,箭头居中显示; 前四种可以支持与运算,如:
    * Qt::AlignLeft|Qt::AlignRight或更多;
    */
    void setArrowAlignment(Qt::Alignment flag); //动态箭头显示位置;
    void setActiveColors(const QColor& bk, const QColor& fk); //bk:动态箭头背景色;fk:动态箭头闪动色;
    void setArrowSize(int width, int height, int space); //设置箭头的尺寸,方便调试;
    void setArrowNum(int num); //设置一个箭头组内箭头的个数;

    bool directUp() const{return m_directUp;}
protected:
    void paintEvent(QPaintEvent* event);
    void mousePressEvent(QMouseEvent* event);
    void enterEvent(QEvent* event);
    void leaveEvent(QEvent* event);

signals:
    void clicked();

private:
    void drawArrow(QPainter* painter,int x0, int x, int y);

private:
    bool    m_hovered = false;
    bool    m_pressed = false;
    bool    m_directUp = false; //箭头向上还是向下;
    int     m_index = 0; //当前高亮的箭头位置;

private:
    uint        m_num = 3; //箭头个数;
    enum
    { //默认;
        Gap = 5,  //箭头离字体的距离;
        ArrowWidth = 20,//单个箭头的横向宽度;
        ArrowHeight = 10,//单个箭头的垂直高度;
    };

    QString             m_text = "";
    QTimer*             m_timeout;

private:
    int                 m_gap = Gap; //箭头离字体的距离;
    int                 m_arrowWidth = ArrowWidth; //单个箭头的横向宽度;
    int                 m_arrowHeight = ArrowHeight; //单个箭头的垂直高度;
    Qt::Alignment       m_alignment = Qt::AlignLeft; //箭头的显示方位;
    QColor              m_bkColor = QColor(Qt::gray); //箭头背景色;
    QColor              m_fkColor = QColor(Qt::red); //箭头闪动色;
};

#endif // ARROWLABEL_H


arrowlabel.cpp ===> 

#include "arrowlabel.h"

#include <QPaintEvent>
#include <QPainter>
#include <QMouseEvent>
#include <QTimer>

ArrowLabel::ArrowLabel(bool up, QWidget* parent) : QLabel(parent), m_directUp(up)
{
    this->setMouseTracking(true);
    this->setAutoFillBackground(true);

    m_timeout = new QTimer(this);
    m_timeout->setInterval(200);
    connect(m_timeout,&QTimer::timeout,[this](){
        if(m_directUp)
        {
            m_index--;
            if(m_index<0)
                m_index = m_num-1;
        }
        else
        {
            m_index++;
            if(m_index>=m_num)
                m_index = 0;
        }
        this->update();
    });
}

void ArrowLabel::setArrowAlignment(Qt::Alignment flag)
{
    m_alignment = flag;
}

void ArrowLabel::setActiveColors(const QColor &bk, const QColor &fk)
{
    m_bkColor = bk;
    m_fkColor = fk;
}
void ArrowLabel::setArrowSize(int width, int height, int space)
{
    m_arrowWidth = width;
    m_arrowHeight = height;
    m_gap = space;
}

void ArrowLabel::setArrowNum(int num)
{
    if(num < 1)
        m_num = 1;
    m_num = num;
}

void ArrowLabel::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    QString txt = m_text;
    QFontMetrics fm(font());
    int txtWidth = fm.width(txt);
    int txtHeight = fm.height();

    QPen pen;
    int x0, x, y; //x0为箭头组的x轴中心线; x,y为箭头组的x,y位置;
    
    painter.save();

    if(m_hovered)
    {
        if(m_alignment&Qt::AlignCenter)
        {
            this->setText("");
            x0 = width()/2;
            x = x0 - m_arrowWidth/2;
            y = height()/2 - m_num*m_arrowHeight/2;
            drawArrow(&painter,x0,x,y);
        }
        else
        {
            if(m_alignment&Qt::AlignLeft)
            {
                x0 = width()/2 - txtWidth/2 - m_arrowWidth/2 - m_gap;
                x = x0 - m_arrowWidth/2;
                y = height()/2 - m_num*m_arrowHeight/2;
                drawArrow(&painter,x0,x,y);
            }

            if(m_alignment&Qt::AlignTop)
            {
                x0 = width()/2;
                x = x0 - m_arrowWidth/2;
                int left,top, right, bottom;
                this->getContentsMargins(&left,&top,&right,&bottom);
                y = top + m_gap + m_arrowHeight; // height()/2 - m_arrowHeight/2 - gap;
                drawArrow(&painter,x0,x,y);
            }

            if(m_alignment&Qt::AlignRight)
            {
                x0 = width()/2 + txtWidth/2 + m_arrowWidth/2 + m_gap;
                x = x0 - m_arrowWidth/2;
                y = height()/2 - m_num*m_arrowHeight/2;
                drawArrow(&painter,x0,x,y);
            }

            if(m_alignment&Qt::AlignBottom)
            {
                x0 = width()/2;
                x = x0 - m_arrowWidth/2;
                y = height()/2 + txtHeight/2 + m_gap;

                drawArrow(&painter,x0,x,y);
            }
        }
    }

    pen.setColor(Qt::gray);
    painter.setPen(pen);
    painter.drawRect(1,1,width()-2,height()-2);
    painter.restore();

    QLabel::paintEvent(event);
}

ArrowLabel::mousePressEvent(QMouseEvent *event)
{
    if(Qt::LeftButton == event->button())
    {
        emit clicked();
        m_directUp = !m_directUp;
        m_pressed = !m_pressed;
        m_index = m_directUp ? (m_num-1) : 0;
        this->update();
    }
    QLabel::mousePressEvent(event);
}

void ArrowLabel::enterEvent(QEvent *event)
{
    m_index = 0;
    m_text = this->text();
    m_hovered = true;
    m_timeout->start();
    QLabel::enterEvent(event);
}

void ArrowLabel::leaveEvent(QEvent *event)
{
    m_index = 0;
    this->setText(m_text);
    m_hovered = false;
    m_timeout->stop();
    this->update();
    QLabel::leaveEvent(event);
}

void ArrowLabel::drawArrow(QPainter* painter,int x0, int x, int y)
{
    QPen pen;
    for(int i=0;i<m_num;i++)
    {
        QPoint pt1 = m_directUp ? QPoint(x,y+m_arrowHeight) : QPoint(x,y);
        QPoint pt2 = m_directUp ? QPoint(x0,y) : QPoint(x0,y+m_arrowHeight);
        QLine line1(pt1,pt2);

        pt1 = m_directUp ? QPoint(x0,y) : QPoint(x0,y+m_arrowHeight);
        pt2 = m_directUp ? QPoint(x0+m_arrowWidth/2,y+m_arrowHeight) : QPoint(x0+m_arrowWidth/2,y);
        QLine line2(pt1,pt2);
        y += m_arrowHeight;

        pen.setColor(i==m_index ? m_fkColor : m_bkColor);
        painter->setPen(pen);
        painter->drawLine(line1);
        painter->drawLine(line2);
    }
}


widget.cpp =====>

#include <QLayout>
#include "arrowlabel.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    ArrowLabel * lab = new ArrowLabel(false,this);
    lab->setText(QString::fromWCharArray(L"展开"));
    lab->setFixedSize(200,100);
    lab->setArrowAlignment(Qt::AlignTop|Qt::AlignBottom|Qt::AlignLeft|Qt::AlignRight);
    lab->setActiveColors(QColor(Qt::black),QColor(Qt::red));
    lab->setAlignment(Qt::AlignCenter);
    lab->setArrowSize(10,8,5);
    lab->setArrowNum(4);
    lab->setStyleSheet("QLabel{font-size:20px;background-color:lightgray;}");

    connect(lab,&ArrowLabel::clicked,[=](){
        if(!lab->directUp()){
            lab->setText(QString::fromWCharArray(L"收起"));
            lab->setArrowAlignment(Qt::AlignTop|Qt::AlignLeft|Qt::AlignRight);
        }else{
            lab->setText(QString::fromWCharArray(L"展开"));
            lab->setArrowAlignment(Qt::AlignBottom|Qt::AlignLeft|Qt::AlignRight);
        }
    });

    QHBoxLayout * mainlayout = new QHBoxLayout;
    mainlayout->addWidget(lab);
    this->setLayout(mainlayout);

    this->setFixedSize(600,500);
}



  评论这张
 
阅读(50)| 评论(0)
推荐

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018