这里先介绍两种其它网友的方法。
方法一:
通过drawPie和底色来控制。
void Widget::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
painter.setPen(QPen(Qt::transparent,4,Qt::SolidLine));
painter.setBrush(QBrush(QColor("red")));
QRect rect(0,0,200,200);
QRect rect1(50, 50, 100, 100);
painter.drawPie(rect,270*16,-90*16);
painter.setBrush(QBrush(QColor("white")));
painter.drawPie(rect1,270*16,-90*16);
}
方法二:
通过QRegion 的subtracted来控制圆环的区域,此方法比较巧妙。
void MainWindow::paintEvent(QPaintEvent* event)
{
QPainter painter(this);
painter.save();
//设置反锯齿
painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform | QPainter::Qt4CompatiblePainting);
QRect drawRect = event->rect();
QRegion region(drawRect.adjusted(10,10,-10,-10),QRegion::Ellipse);
drawRect.setSize(QSize(drawRect.width()/2,drawRect.height()/2));
drawRect.moveTopLeft(QPoint((event->rect().width() - drawRect.width())/2,(event->rect().height() - drawRect.height())/2));
QRegion region2(drawRect,QRegion::Ellipse);
QPainterPath painterPath;
painterPath.addRegion(region.subtracted(region2));
painter.fillPath(painterPath,Qt::red);
event->accept();
painter.restore();
}
但是以上两种方法都无法实现绘制透明的任意角度的圆环,且还需要支持渐变色。
我绘制圆环实现逻辑:
通过Qt的QPainterPath来实现,通过三角函数计算x,y坐标点围成一个环形区域。
.h
class MGradientLabel : public QLabel
{
Q_OBJECT
public:
MGradientLabel(QWidget* parent = nullptr);
~MGradientLabel();
void setPipeWidth(int num); //设置环道宽度
void setAngleRange(int staAng, int endAng); //设置环道范围
void setPipeColor(QColor staColor = QColor("#ffffff"), QColor endColor = QColor("#000000"), double stop1 = 0, double stop2 = 0); //设置环道颜色
protected:
void paintEvent(QPaintEvent *);
private:
int m_pipeWidth = 20;
int m_staAng = 210;
int m_endAng = 330;
QColor m_staColor = QColor("#ffffff");
QColor m_endColor = QColor("#000000");
double m_stop1 = 0;
double m_stop2 = 0;
};
.cpp
MGradientLabel::MGradientLabel(QWidget *parent):QLabel(parent)
{
}
MGradientLabel::~MGradientLabel()
{
}
void MGradientLabel::setPipeColor(QColor staColor, QColor endColor, double stop1, double stop2)
{
m_staColor = staColor;
m_endColor = endColor;
m_stop1 = stop1;
m_stop2 = stop2;
}
void MGradientLabel::setPipeWidth(int num)
{
m_pipeWidth = num;
}
void MGradientLabel::setAngleRange(int staAng,int endAng)
{
m_staAng = staAng;
m_endAng = endAng;
}
void MGradientLabel::paintEvent(QPaintEvent *)
{
QPainter p(this);
// 反走样
p.setRenderHints(QPainter::SmoothPixmapTransform|QPainter::Antialiasing);
// 设置画笔颜色、宽度
p.setPen(Qt::NoPen);
p.translate(width()/2,height()/2);
// 设置渐变色
QConicalGradient conical(0, 0, m_staAng);
conical.setColorAt(0, m_staColor);
conical.setColorAt(m_stop1, m_staColor);
conical.setColorAt(m_stop2, m_endColor);
// 设置画刷填充
p.setBrush(conical);
QPainterPath painterPath;
painterPath.moveTo((width()/2-m_pipeWidth)*qSin((m_staAng+90)*(M_PI/180)),(width()/2-m_pipeWidth)*qCos((m_staAng+90)*(M_PI/180)));
painterPath.lineTo(width()/2*qSin((m_staAng+90)*(M_PI/180)),width()/2*qCos((m_staAng+90)*(M_PI/180)));
painterPath.arcTo(QRect(-width()/2,-height()/2,width(),height()),m_staAng,m_endAng - m_staAng);
painterPath.lineTo((width()/2-m_pipeWidth)*qSin((m_endAng - 270)*(M_PI/180)),(height()/2-m_pipeWidth)*qCos((m_endAng - 270)*(M_PI/180)));
painterPath.arcTo(QRect(-width()/2 + m_pipeWidth,-height()/2 + m_pipeWidth,width() - m_pipeWidth*2,height() - m_pipeWidth*2),m_endAng,-(m_endAng - m_staAng));
p.drawPath(painterPath);
}