閒來無事,簡單做了一個基於QT的仿“探探”雷達掃描控件,效果圖如下
核心代碼
1,繪製掃描
void QTanTanScanning::drawScanning(QPainter *painter)
{
painter->save();
QConicalGradient conical(0, 0, arc);
scannigColor.setAlpha(50);
conical.setColorAt(0, scannigColor);
scannigColor.setAlpha(0);
conical.setColorAt(1, scannigColor);
QPen pen(conical, 2, Qt::SolidLine, Qt::FlatCap, Qt::MPenJoinStyle);
painter->setPen(pen);
painter->setBrush(conical);
painter->drawPie(QRect(- ringMaxR, - ringMaxR, ringMaxR << 1, ringMaxR << 1), arc * 16, 360 * 16);
painter->drawArc(QRect(- ringMaxR, - ringMaxR, ringMaxR << 1, ringMaxR << 1), 0, 360 * 16);
painter->restore();
}
2,繪製擴散圈
void QTanTanScanning::drawRings(QPainter *painter)
{
painter->save();
painter->setBrush(Qt::NoBrush);
QVector<struct RingData>::iterator iter = rings.begin();
while(iter != rings.end())
{
struct RingData currRing = *iter;
int radius = currRing.radius;
//繪製圓弧方法繪製圓環
float penWidth = currRing.penWidth;
QRectF rect(-radius + penWidth / 2, -radius + penWidth / 2, radius * 2 - penWidth, radius * 2 - penWidth);
//可以自行修改畫筆的後三個參數,形成各種各樣的效果,例如Qt::FlatCap改爲Qt::RoundCap可以產生圓角效果
ringColor.setAlpha(255 - currRing.alpha);
QPen pen(ringColor, penWidth, Qt::SolidLine, Qt::FlatCap, Qt::MPenJoinStyle);
//繪製總範圍角度圓弧
pen.setColor(ringColor);
painter->setPen(pen);
painter->drawArc(rect, 0 * 16, 360 * 16);
iter++;
}
painter->restore();
}
3,繪製中間圖片按鈕
void QTanTanScanning::drawCenterRing(QPainter *painter)
{
painter->save();
QPixmap pixmap(":/image/kt.jpeg");
QPainterPath path;
path.addEllipse(QPoint(0, 0), centerR, centerR);
painter->setClipPath(path);
QRect rect(-centerR, -centerR, centerR * 2, centerR * 2);
painter->drawPixmap(rect, pixmap);
int penWidth = 3;
//可以自行修改畫筆的後三個參數,形成各種各樣的效果,例如Qt::FlatCap改爲Qt::RoundCap可以產生圓角效果
QPen pen(Qt::white, penWidth, Qt::SolidLine, Qt::FlatCap, Qt::MPenJoinStyle);
painter->setPen(pen);
painter->drawArc(rect, 0, 360 * 16);
painter->restore();
}
4,中間按鈕動畫控制
QPropertyAnimation *anim1 = new QPropertyAnimation(this, "");
anim1->setStartValue(40);
anim1->setEndValue(50);
anim1->setDuration(300);
QPropertyAnimation *anim2 = new QPropertyAnimation(this, "");
anim2->setStartValue(50);
anim2->setEndValue(30);
anim2->setDuration(300);
QPropertyAnimation *anim3 = new QPropertyAnimation(this, "");
anim3->setStartValue(30);
anim3->setEndValue(40);
anim3->setDuration(300);
animationGroup = new QSequentialAnimationGroup() ;
animationGroup->addAnimation(anim1);
animationGroup->addAnimation(anim2);
animationGroup->addAnimation(anim3);
connect(anim1, SIGNAL(valueChanged(QVariant)), this, SLOT(updateRadius(QVariant)));
connect(anim2, SIGNAL(valueChanged(QVariant)), this, SLOT(updateRadius(QVariant)));
connect(anim3, SIGNAL(valueChanged(QVariant)), this, SLOT(updateRadius(QVariant)));
鼠標事件,判斷點擊和開始動畫
void QTanTanScanning::mousePressEvent(QMouseEvent *event)
{
if(!m_pressflag)
{
QPoint pressedPoint = event->pos();
QPointF realPos = pressedPoint - rect().center();
QMatrix qMatrix;
int width = this->width();
int height = this->height();
int side = qMin(width, height);
qMatrix.scale(side / 200.0, side / 200.0);
QRegion mEllipse = QRegion(-centerRingR, -centerRingR, centerRingR * 2, centerRingR * 2, QRegion::Ellipse);
mEllipse = qMatrix.map(mEllipse);
if( mEllipse.contains(realPos.toPoint()))
{
m_pressflag = true;
//centerRingR = 50;
animationGroup->stop();
update();
}
}
}
void QTanTanScanning::mouseReleaseEvent(QMouseEvent* event)
{
if(m_pressflag)
{
m_pressflag = false;
struct RingData ring;
ring.radius = centerRingR;
ring.alpha = 255;
ring.penWidth = 3;
rings.push_back(ring);
//centerRingR = 40;
animationGroup->start();
update();
}
}
掃描和擴散定時動態
void QTanTanScanning::ringsTimerWork()
{
QVector<struct RingData>::iterator iter = rings.begin();
while(iter != rings.end())
{
struct RingData currRing = *iter;
if(currRing.radius < ringMaxR)
{
currRing.radius += ringsRStep;
currRing.alpha = currRing.radius * (255 / ringMaxR);
currRing.penWidth = 3.0 - currRing.radius * (3.0 / ringMaxR);
*iter = currRing;
iter++;
}
else
{
rings.erase(iter);
}
}
update();
}
void QTanTanScanning::timerWork()
{
arc--;
if (arc == 0)
arc = 360;
update();
}
源碼文件已上傳