1. 程式人生 > 其它 >Qt自定義圓形環狀選單

Qt自定義圓形環狀選單

技術標籤:Qt開發筆記c++qt

Qt自定義圓形環狀選單

先看實現的效果
在這裡插入圖片描述

可設定圓環背景色、Hover扇形的顏色、箭頭顏色、動畫速度,核心程式碼如下

1、初始化設定背景透明,預設開啟旋轉和縮放動畫

	q->setFixedSize(180, 180);
    diameter = 150;
    smallDiameter = calcInCircleRadius() * 2;
    q->setMouseTracking(true);

    q->setWindowFlags(Qt::FramelessWindowHint | Qt::Dialog);
    q-
>setAttribute(Qt::WA_TranslucentBackground); q->setRotateAnimationEnabled(true); q->setZoomAnimationEnabled(true);

2、重寫滑鼠事件,實現拖動,點選等功能

void CircleMenu::mousePressEvent(QMouseEvent *event)
{
    if(event->button() != Qt::LeftButton){
        return ;
    }
    Q_D(CircleMenu);
    d-
>pressed = true; d->startPos = event->pos(); QPointF center(width() / 2.0, height() / 2.0); double distance = std::sqrt(std::pow(center.x() - d->startPos.x(), 2) + std::pow(center.y() - d->startPos.y(), 2)); d->pressPosIsInSmallCircle = distance < d->calcInCircleRadius
(); } void CircleMenu::mouseMoveEvent(QMouseEvent *event) { Q_D(CircleMenu); if(d->canMove && d->pressed && d->pressPosIsInSmallCircle){ this->move(this->pos() + event->pos() - d->startPos); d->moved = true; } if(d->isMenuVisible){ auto old = d->currentArea; d->currentArea = d->calcArea(event->pos()); update(); if(!d->pressed){ d->updateTip(event->globalPos()); } if(d->pressed && old != d->currentArea && !d->pressPosIsInSmallCircle){ d->pressedMovedArea = d->currentArea; emit sigAreaChanged(d->currentArea); } } } void CircleMenu::mouseReleaseEvent(QMouseEvent *event) { Q_D(CircleMenu); d->pressed = false; if(event->button() != Qt::LeftButton){ return ; } if(d->isMenuVisible){ auto old = d->pressedMovedArea; d->pressedMovedArea = d->calcArea(event->pos()); if(old != d->pressedMovedArea){ emit sigAreaChanged(d->pressedMovedArea); } emit sigClicked(d->pressedMovedArea); } if(!d->isPopup && !d->moved){ QPoint rela = event->pos() - QPoint(width() / 2, height() / 2); int dis = std::sqrt(rela.x() * rela.x() + rela.y() * rela.y()); if(dis > d->smallDiameter / 2){ return ; } d->isMenuVisible = !d->isMenuVisible; d->aniGroup->setDirection(d->isMenuVisible ? QVariantAnimation::Forward : QVariantAnimation::Backward); d->aniGroup->start(); } d->moved = false; }

3、重寫event事件,點選主介面空白區域關閉視窗

bool CircleMenu::event(QEvent *event)
{
    switch (event->type()) {
    case QEvent::FocusOut:
    case QEvent::WindowDeactivate:
        if(d_func()->isPopup){
            d_func()->hidePopup();
        }
        break;
    case QEvent::Leave:
        d_func()->currentArea = Unknown;
        update();
        break;
    default:
        break;
    }
    return QWidget::event(event);
}

4、最後是繪圖程式碼

void CircleMenu::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event)
    Q_D(CircleMenu);
    QPainter painter(this);
    if(d->isPopup){
        painter.fillRect(rect(), QBrush(QColor(0, 0, 0, 1)));
    }

    painter.setRenderHints(QPainter::SmoothPixmapTransform | QPainter::Antialiasing);
    QPointF center(width() / 2.0, height() / 2.0);
    painter.translate(center);
    painter.rotate(d->angle);

    d->drawCircle(&painter);
    d->drawPie(&painter);
    d->drawArrow(&painter);
    d->drawImages(&painter);
}

工程程式碼下載連結:Qt圓形環狀選單