#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);
}
评论