#include "FrameLessWidget.h" #include #include #include #include using changeSize = std::function; FrameLessWidget::FrameLessWidget(QWidget *parent) : QWidget(parent) { setMouseTracking(true); setAttribute(Qt::WA_Hover); setAttribute(Qt::WA_TranslucentBackground); //setAttribute(Qt::WA_Mapped); setWindowFlags( Qt::Window | Qt::FramelessWindowHint | Qt::WindowSystemMenuHint | Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint ); space = 0; radius = 16; topMargin = 16; bottomMargin = 16; rightMargin = 16; leftMargin = 16; shapes.append ({ Qt::SizeFDiagCursor, Qt::SizeVerCursor, Qt::SizeBDiagCursor, Qt::SizeHorCursor, Qt::ArrowCursor, Qt::SizeHorCursor, Qt::SizeBDiagCursor, Qt::SizeVerCursor, Qt::SizeFDiagCursor, Qt::ArrowCursor }); changeSizes.append ({ [this]() { //R11 setGeometry(startX + dx, startY + dy, qMax(startW - dx, getMinWidth()), qMax(startH - dy, getMinHeight())); }, [this]() { //R12 setGeometry(startX, startY + dy, qMax(startW, getMinWidth()), qMax(startH - dy, getMinHeight())); }, [this]() { //R13 setGeometry(startX, startY + dy, qMax(startW + dx, getMinWidth()), qMax(startH - dy, getMinHeight())); }, [this]() { //R21 setGeometry(startX + dx, startY, qMax(startW - dx, getMinWidth()), qMax(startH, getMinHeight())); }, []() { //R22 }, [this]() { //R23 setGeometry(startX, startY, qMax(startW + dx, getMinWidth()), qMax(startH, getMinHeight())); }, [this]() { //R31 setGeometry(startX + dx, startY, qMax(startW - dx, getMinWidth()), qMax(startH + dy, getMinHeight())); }, [this]() { //R32 setGeometry(startX, startY, qMax(startW, getMinWidth()), qMax(startH + dy, getMinHeight())); }, [this]() { //R33 setGeometry(startX, startY, qMax(startW + dx, getMinWidth()), qMax(startH + dy, getMinHeight())); }, []() { //null } }); } int FrameLessWidget::getMinWidth() { return 0; } int FrameLessWidget::getMinHeight() { return 0; } void FrameLessWidget::paintEvent(QPaintEvent* event) { QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing); painter.fillRect(rect(), QColor(255, 255, 255, 1)); //不能改 让他不是透明的 // painter.fillRect(r11, Qt::blue); // painter.fillRect(r12, Qt::darkCyan); // painter.fillRect(r13, Qt::green); // painter.fillRect(r21, Qt::gray); // painter.fillRect(r22, Qt::red); // painter.fillRect(r23, Qt::darkGreen); // painter.fillRect(r31, Qt::black); // painter.fillRect(r32, Qt::darkRed); // painter.fillRect(r33, Qt::darkBlue); 否则改变大小失效 // https://blog.csdn.net/liushuaitong/article/details/122117384 // https://www.cnblogs.com/linuxAndMcu/p/11057347.html QRect rect = r22; //painter.drawRoundedRect(rect, radius, radius); //画阴影边框 auto color = background_color; // int xRadius = r22.width(); // int yRadius = r22.height(); int xRadius = radius; int yRadius = radius; int mul = 2; int n = topMargin/mul; auto max = double(n*n*n); double value = background_color.alpha(); for (int i = 0; i < n; i++) { if (i == 0) { painter.setPen(Qt::NoPen); QColor b = QColor::fromRgb(background_color.red(), background_color.green(), background_color.blue()); painter.setBrush(b); painter.drawRoundedRect(rect, xRadius, yRadius); painter.setBrush(Qt::NoBrush); } else { double rate = (i*i*i)/max; color.setAlpha(static_cast(value * (1-rate))); painter.setBrush(color); painter.drawRoundedRect(rect.adjusted(-i * mul, -i * mul, i * mul, i * mul), xRadius, yRadius); } } painter.end(); } bool FrameLessWidget::event(QEvent *event) { if (event->type() == QEvent::HoverMove) { auto *hoverEvent = static_cast(event); // qDebug() << hoverEvent->pos(); QMouseEvent mouseEvent(QEvent::MouseMove, hoverEvent->pos(), Qt::NoButton, Qt::NoButton, Qt::NoModifier); mouseMoveEvent(&mouseEvent); } return QWidget::event(event); } void FrameLessWidget::setPos() { x1 = 0; x2 = x1 + leftMargin + space; x3 = width() - rightMargin - space; y1 = 0; y2 = y1 + topMargin + space; y3 = height() - bottomMargin - space; } void FrameLessWidget::setRs() { int w1 = x2 - x1, w2 = x3 - x2, w3 = width() - x3; int h1 = y2 - y1, h2 = y3 - y2, h3 = height() - y3; r11.setRect(x1, y1, w1, h1); r12.setRect(x2, y1, w2, h1); r13.setRect(x3, y1, w3, h1); r21.setRect(x1, y2, w1, h2); r22.setRect(x2, y2, w2, h2); r23.setRect(x3, y2, w3, h2); r31.setRect(x1, y3, w1, h3); r32.setRect(x2, y3, w2, h3); r33.setRect(x3, y3, w3, h3); } void FrameLessWidget::mousePressEvent(QMouseEvent *event) { auto pos = event->pos(); if (event->button() != Qt::LeftButton) return; if (changingSize) return; if (drag_moving) return; curR = getRectType(pos); if (curR != Drag_R) { changingSize = true; setCursor(shapes[curR]); } else { drag_moving = true; setCursor(Qt::ClosedHandCursor); } if (changingSize || drag_moving) { startX = this->x(); startY = this->y(); startGlobalX = event->globalPos().x(); startGlobalY = event->globalPos().y(); startW = width(); startH = height(); } } void FrameLessWidget::mouseReleaseEvent(QMouseEvent *event) { if (changingSize) { changingSize = false; } if (drag_moving) { drag_moving = false; setCursor(Qt::OpenHandCursor); } } void FrameLessWidget::mouseMoveEvent(QMouseEvent *event) { RectType ret = getRectType(event->pos()); if (ret == Drag_R) { if (!drag_moving) { setCursor(Qt::OpenHandCursor); } } else { setCursor(shapes[ret]); } if (!changingSize && !drag_moving) { return; } const QPoint &curGlobalPos = event->globalPos(); dx = curGlobalPos.x() - startGlobalX; dy = curGlobalPos.y() - startGlobalY; if (changingSize) { changeSizes[curR](); } else if (drag_moving) { move(startX + dx, startY + dy); } } RectType FrameLessWidget::getRectType(const QPoint &p) const { if (p.y() < y2) { if (p.x() < x2) return R11; if (p.x() > x3) return R13; if (p.x() < (x2 + x3)/4) return Drag_R; return R12; } if (p.y() > y3) { if (p.x() < x2) return R31; if (p.x() > x3) return R33; return R32; } if (p.x() < x2) return R21; if (p.x() > x3) return R23; return R22; } void FrameLessWidget::resizeEvent(QResizeEvent *event) { if (isMaximized()) { QRect screenSize = screen()->availableGeometry() .adjusted(-leftMargin, -topMargin, rightMargin, bottomMargin); setGeometry(screenSize); } setPos(); setRs(); } void FrameLessWidget::showEvent(QShowEvent *event) { QWidget::showEvent(event); }