#pragma once #include "global.h" enum class Mouse_State { Default, Pressed, Entered }; struct Border { QColor border_color = Qt::red; int len = 4; }; using Handle_Mouse = std::function; struct Background : Paintable { QGraphicsDropShadowEffect shadow_effect; Border* border{}; std::map map; Qt::SizeMode mode = Qt::RelativeSize; qreal radius = 0.1; bool enter = false; Mouse_State mouse_state = Mouse_State::Default; std::vector mouse_handlers; void set_border(const QColor& border_color, int len = 1) { if (!border) border = new Border; border->border_color = border_color; border->len = len; } void set_effect(QWidget* that) { shadow_effect.setBlurRadius(10); // 设置模糊半径 shadow_effect.setOffset(5, 5); // 设置阴影偏移量(x, y) shadow_effect.setColor(Qt::black); // 设置阴影颜色 that->setGraphicsEffect(&shadow_effect); } void set_color(const QColor& color) { map[Mouse_State::Default] = color; double r = color.red(); double g = color.green(); double b = color.blue(); // int alpha = color.alpha(); double upper = 1.6; double lower = 0.4; auto ur = qMin(255, (int)(r * upper)); auto ug = qMin(255, (int)(g * upper)); auto ub = qMin(255, (int)(b * upper)); int lr = (int)(r * lower); int lg = (int)(g * lower); int lb = (int)(b * lower); map[Mouse_State::Pressed] = QColor(ur, ug, ub); map[Mouse_State::Entered] = QColor(lr, lg, lb); } Event_Type mouse_event(QEvent::Type t, QMouseEvent* e) override { if (t == QEvent::MouseButtonPress) { mouse_state = Mouse_State::Pressed; } else if (t == QEvent::MouseButtonRelease) { if (enter) mouse_state = Mouse_State::Entered; else mouse_state = Mouse_State::Default; } for (auto& handler : mouse_handlers) { handler(t, e); } return Event_Type::refresh; } Event_Type event(QEvent::Type t, QEvent* e) override { if (t == QEvent::Enter) { enter = true; mouse_state = Mouse_State::Entered; return Event_Type::refresh; } else if (t == QEvent::Leave) { enter = false; mouse_state = Mouse_State::Default; return Event_Type::refresh; } return Paintable::event(t, e); } void paint(QPainter* painter, QRect rect) override { painter->save(); int half_pen_width = 0; QRect adjusted_rect = rect.adjusted(half_pen_width, half_pen_width, -half_pen_width, -half_pen_width); qreal x_radius, y_radius; get_rounded_rect_radius(adjusted_rect, x_radius, y_radius); QPainterPath border_path; border_path.addRoundedRect(adjusted_rect, x_radius, y_radius); QRect inner_rect = adjusted_rect; if (border) { inner_rect.adjust(border->len, border->len, -border->len, -border->len); } // 内部区域边距 QPainterPath inner_path; inner_path.addRoundedRect(inner_rect, x_radius, y_radius); QColor c = map[mouse_state]; painter->setPen(Qt::NoPen); if (c.isValid()) { painter->save(); if (border) { painter->setBrush(border->border_color); painter->drawPath(border_path); } painter->setBrush(c); painter->drawPath(inner_path); painter->restore(); } else { if (border) { border_path = border_path.subtracted(inner_path); painter->setBrush(border->border_color); painter->drawPath(border_path); } } painter->restore(); } void set_radius(Qt::SizeMode mode, qreal value) { this->mode = mode; this->radius = value; } protected: void get_rounded_rect_radius(const QRect& rect, qreal& x_radius, qreal& y_radius) const { if (mode == Qt::RelativeSize) { x_radius = rect.width() * radius; y_radius = rect.height() * radius; } else { x_radius = radius; y_radius = radius; } } };