Qt C++ 实现无边框窗口
// widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QDebug>
#include <QHBoxLayout>
#include <QMouseEvent>
#include <QPushButton>
#include <QString>
#include <QWidget>
#define PADDING 6
enum Location {
TOP,
BOTTOM,
LEFT,
RIGHT,
TOP_LEFT,
TOP_RIGHT,
BOTTOM_LEFT,
BOTTOM_RIGHT,
CENTER
};
class Widget : public QWidget {
Q_OBJECT
public:
Widget(QWidget* parent = nullptr);
~Widget();
protected:
void mousePressEvent(QMouseEvent* event);
void mouseMoveEvent(QMouseEvent* event);
void mouseReleaseEvent(QMouseEvent* event);
private:
void setCursorShape(const QPoint& point);
private:
// 左键有没有按下
bool isLeftPressed;
// 鼠标按下的位置 偏移
QPoint mouseOffset;
Location location;
};
#endif // WIDGET_H
// widget.cpp
#include "widget.h"
Widget::Widget(QWidget* parent) : QWidget(parent) {
// 设置窗口的宽高
this->setMinimumWidth(500);
this->setMinimumHeight(300);
// 设置背景色
this->setStyleSheet("background: #303030");
// 添加两个按钮 - 水平布局
QHBoxLayout* layout = new QHBoxLayout(this);
layout->setSpacing(10);
layout->setContentsMargins(10, 10, 10, 10);
QPushButton* btn1 = new QPushButton("确定");
QPushButton* btn2 = new QPushButton("取消");
layout->addWidget(btn1);
layout->addWidget(btn2);
QString style = R"(
QPushButton {
background-color: rgb(64, 64, 64);
font: 16px "Microsoft YaHei";
color: rgb(200, 200, 200);
border-radius: 5px;
padding: 5px;
}
QPushButton:hover {
background-color: rgb(40, 40, 40);
}
QPushButton:pressed {
background-color: rgb(64, 64, 64);
}
)";
btn1->setStyleSheet(style);
btn2->setStyleSheet(style);
// 去除标题栏
this->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowSystemMenuHint);
this->isLeftPressed = false;
// 开启鼠标追踪
this->setMouseTracking(true);
}
Widget::~Widget() {}
void Widget::mousePressEvent(QMouseEvent* event) {
switch (event->button()) {
case Qt::RightButton:
this->close();
break;
case Qt::LeftButton:
this->isLeftPressed = true;
if (location == CENTER) {
this->mouseOffset =
event->globalPos() - this->frameGeometry().topLeft();
}
break;
}
}
void Widget::mouseMoveEvent(QMouseEvent* event) {
QPoint globalPos = event->globalPos();
QRect rect = this->rect();
QPoint topLeft = mapToGlobal(rect.topLeft());
QPoint bottomRight = mapToGlobal(rect.bottomRight());
// 1. 鼠标未按下
if (!this->isLeftPressed) {
this->setCursorShape(globalPos);
return;
}
// 2. 鼠标按下, 在CENTER位置按下
if (this->location == CENTER) {
move(globalPos - mouseOffset);
event->accept();
return;
}
// 3. 缩放
QRect rMove(topLeft, bottomRight);
switch (location) {
case TOP:
// 窗口达到最小高度后,会被鼠标 “向下推走”
if (bottomRight.y() - globalPos.y() > this->minimumHeight())
rMove.setY(globalPos.y());
break;
case BOTTOM:
rMove.setHeight(globalPos.y() - topLeft.y());
break;
case LEFT:
if (bottomRight.x() - globalPos.x() > this->minimumWidth())
rMove.setX(globalPos.x());
break;
case RIGHT:
rMove.setWidth(globalPos.x() - topLeft.x());
break;
case TOP_LEFT:
if (bottomRight.y() - globalPos.y() > this->minimumHeight())
rMove.setY(globalPos.y());
if (bottomRight.x() - globalPos.x() > this->minimumWidth())
rMove.setX(globalPos.x());
break;
case TOP_RIGHT:
if (bottomRight.y() - globalPos.y() > this->minimumHeight())
rMove.setY(globalPos.y());
rMove.setWidth(globalPos.x() - topLeft.x());
break;
case BOTTOM_LEFT:
rMove.setHeight(globalPos.y() - topLeft.y());
if (bottomRight.x() - globalPos.x() > this->minimumWidth())
rMove.setX(globalPos.x());
break;
case BOTTOM_RIGHT:
rMove.setHeight(globalPos.y() - topLeft.y());
rMove.setWidth(globalPos.x() - topLeft.x());
break;
default:
break;
}
this->setGeometry(rMove);
}
void Widget::mouseReleaseEvent(QMouseEvent* event) {
if (event->button() == Qt::LeftButton) {
isLeftPressed = false;
}
}
void Widget::setCursorShape(const QPoint& point) {
QRect rect = this->rect();
QPoint topLeft = mapToGlobal(rect.topLeft());
QPoint bottomRight = mapToGlobal(rect.bottomRight());
int x = point.x();
int y = point.y();
if (x >= topLeft.x() && x <= topLeft.x() + PADDING && y >= topLeft.y() &&
y <= topLeft.y() + PADDING) {
// 左上角
location = TOP_LEFT;
this->setCursor(QCursor(Qt::SizeFDiagCursor));
} else if (x <= bottomRight.x() && x >= bottomRight.x() - PADDING &&
y <= bottomRight.y() && y >= bottomRight.y() - PADDING) {
// 右下角
location = BOTTOM_RIGHT;
this->setCursor(QCursor(Qt::SizeFDiagCursor));
} else if (x >= topLeft.x() && x <= topLeft.x() + PADDING &&
y <= bottomRight.y() && y >= bottomRight.y() - PADDING) {
// 左下角
location = BOTTOM_LEFT;
this->setCursor(QCursor(Qt::SizeBDiagCursor));
} else if (x <= bottomRight.x() && x >= bottomRight.x() - PADDING &&
y >= topLeft.y() && y <= topLeft.y() + PADDING) {
// 右上角
location = TOP_RIGHT;
this->setCursor(QCursor(Qt::SizeBDiagCursor));
} else if (x >= topLeft.x() && x <= topLeft.x() + PADDING) {
// 左边
location = LEFT;
this->setCursor(QCursor(Qt::SizeHorCursor));
} else if (x >= bottomRight.x() - PADDING && x <= bottomRight.x()) {
// 右边
location = RIGHT;
this->setCursor(QCursor(Qt::SizeHorCursor));
} else if (y >= topLeft.y() && y <= topLeft.y() + PADDING) {
// 上边
location = TOP;
this->setCursor(QCursor(Qt::SizeVerCursor));
} else if (y >= bottomRight.y() - PADDING && y <= bottomRight.y()) {
// 下边
location = BOTTOM;
this->setCursor(QCursor(Qt::SizeVerCursor));
} else {
location = CENTER;
this->setCursor(QCursor(Qt::ArrowCursor));
}
}
文章来源地址https://www.toymoban.com/news/detail-854084.html
文章来源:https://www.toymoban.com/news/detail-854084.html
到了这里,关于Qt C++ 实现无边框窗口的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!