解决Qt设置无边框后无法通过鼠标拖动修改窗口大小问题

    科技2022-08-09  149

    头文件

    #ifndef ABSTRACTMAINWINDOW_H #define ABSTRACTMAINWINDOW_H #include <QMainWindow> #include <QPainter> #include <QPaintEvent> #include <QStyleOption> #include <QMouseEvent> #include <QPoint> #include <QResizeEvent> class AbstractMainWindow : public QMainWindow { Q_OBJECT enum CursorPosition { None, TopLeft, Top, TopRight, Right, BottomRight, Bottom, BottomLeft, Left }; protected: QPoint m_startPos; bool m_isPressed = false; bool m_followMouseMove = false; Qt::CursorShape m_cursorShape = Qt::ArrowCursor; CursorPosition m_cursorPosition = None; bool m_cursorShapeChangable = true; int m_deltaLength = 10; protected: AbstractMainWindow(QWidget* parent = nullptr); virtual bool construct(); bool event(QEvent *event); void paintEvent(QPaintEvent* e); void mousePressEvent(QMouseEvent *event); void mouseReleaseEvent(QMouseEvent *event); void mouseMoveEvent(QMouseEvent *event); void setCursorShape(Qt::CursorShape shape); public: void setFollowMouseMove(bool value); void setCursorShapeChangable(bool value); }; #endif // ABSTRACTMAINWINDOW_H

    源文件

    #include "AbstractMainWindow.h" #include <QDebug> AbstractMainWindow::AbstractMainWindow(QWidget* parent):QMainWindow(parent) { //设置鼠标追踪 setMouseTracking(true); } bool AbstractMainWindow::construct() { return true; } bool AbstractMainWindow::event(QEvent *event) { if(event->type() == QEvent::HoverMove) { /* 处理无边框后拖拽改变窗口大小问题 */ //左上 auto topLeftGPos = this->pos(); //右上 auto topRightGPos = QPoint(this->geometry().right(),y()); //右下 auto bottomRightGPos = QPoint(this->geometry().right(),this->geometry().bottom()); //左下 auto bottomLeftGPos = QPoint(x(),this->geometry().bottom()); auto event_pos = cursor().pos(); //在右边界 if((topRightGPos.x() - m_deltaLength <= event_pos.x()) && (event_pos.x() <= topRightGPos.x() + m_deltaLength)) { if(m_cursorShape == Qt::ArrowCursor) { if((topRightGPos.y() - m_deltaLength <= event_pos.y()) && (event_pos.y() <= topRightGPos.y() + m_deltaLength)) { m_cursorPosition = TopRight; setCursorShape(Qt::SizeBDiagCursor); } else if((bottomRightGPos.y() - m_deltaLength <= event_pos.y()) && (event_pos.y() <= bottomRightGPos.y() + m_deltaLength)) { m_cursorPosition = BottomRight; setCursorShape(Qt::SizeFDiagCursor); } else { m_cursorPosition = Right; setCursorShape(Qt::SizeHorCursor); } } } //在左边界 else if((topLeftGPos.x() - m_deltaLength <= event_pos.x()) && (event_pos.x() <= topLeftGPos.x() + m_deltaLength)) { if(m_cursorShape == Qt::ArrowCursor) { if((topLeftGPos.y() - m_deltaLength <= event_pos.y()) && (event_pos.y() <= topLeftGPos.y() + m_deltaLength)) { m_cursorPosition = TopLeft; setCursorShape(Qt::SizeFDiagCursor); } else if((bottomLeftGPos.y() - m_deltaLength <= event_pos.y()) && (event_pos.y() <= bottomLeftGPos.y() + m_deltaLength)) { m_cursorPosition = BottomLeft; setCursorShape(Qt::SizeBDiagCursor); } else { m_cursorPosition = Left; setCursorShape(Qt::SizeHorCursor); } } } //在上边界 else if((topLeftGPos.y() - m_deltaLength <= event_pos.y()) && (event_pos.y() <= topLeftGPos.y() + m_deltaLength)) { if(m_cursorShape == Qt::ArrowCursor) { m_cursorPosition = Top; setCursorShape(Qt::SizeVerCursor); } } //在下边界 else if((bottomLeftGPos.y() - m_deltaLength <= event_pos.y()) && (event_pos.y() <= bottomLeftGPos.y() + m_deltaLength)) { if(m_cursorShape == Qt::ArrowCursor) { m_cursorPosition = Bottom; setCursorShape(Qt::SizeVerCursor); } } else { m_cursorPosition = None; setCursorShape(Qt::ArrowCursor); } } return QMainWindow::event(event); } void AbstractMainWindow::paintEvent(QPaintEvent* e) { QStyleOption opt; opt.init(this); QPainter p(this); style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); (void)e; } void AbstractMainWindow::mousePressEvent(QMouseEvent *event) { QMainWindow::mousePressEvent(event); if(m_followMouseMove) { if(event->button() == Qt::LeftButton) { m_isPressed = true; m_startPos = event->globalPos(); } } m_cursorShape = cursor().shape(); } void AbstractMainWindow::mouseReleaseEvent(QMouseEvent *event) { if(m_followMouseMove) m_isPressed = false; QMainWindow::mouseReleaseEvent(event); } void AbstractMainWindow::mouseMoveEvent(QMouseEvent *event) { if(m_followMouseMove) { if(m_isPressed) { if(m_cursorShape == Qt::ArrowCursor) { auto offset = event->globalPos() - m_startPos; m_startPos = event->globalPos(); move(x() + offset.x(),y() + offset.y()); } else { auto offset = event->globalPos() - m_startPos; m_startPos = event->globalPos(); switch(m_cursorPosition) { case TopLeft: { move(x() + offset.x(),y() + offset.y()); resize(width() - offset.x(),height() - offset.y()); break; } case Top: { move(x(),y() + offset.y()); resize(width(),height() - offset.y()); break; } case TopRight: { resize(width() + offset.x(),height() - offset.y()); break; } case Right: { resize(width() + offset.x(),height()); break; } case BottomRight: { resize(width() + offset.x(),height() + offset.y()); break; } case Bottom: { resize(width(),height() + offset.y()); break; } case BottomLeft: { move(x() + offset.x(),y()); resize(width() - offset.x(),height() + offset.y()); break; } case Left: { move(x() + offset.x(),y()); resize(width() - offset.x(),height()); break; } default: break; } } } } QMainWindow::mouseMoveEvent(event); } void AbstractMainWindow::setFollowMouseMove(bool value) { m_followMouseMove = value; } void AbstractMainWindow::setCursorShapeChangable(bool value) { m_cursorShapeChangable = value; } void AbstractMainWindow::setCursorShape(Qt::CursorShape shape) { if(m_cursorShapeChangable) { setCursor(shape); } }

    默认是不开启通过鼠标来移动窗口的,调用setFollowMouseMove(true)即可

    QWidget同理,改个类名就行

    Processed: 0.013, SQL: 8