在使用QT创建窗体的时候,为了使窗口美化,通常不使用QT自带的边框。会调用下面函数去除窗体边框。
setWindowFlags(Qt::FramelessWindowHint)
但是有个问题,当去除了QT自带边框后,窗体就变得不能移动了,也不能改变窗口大小了。这确实是个问题,该怎么去解决呢?
1.重写mousePressEvent\ mouseMoveEvent mouseReleaseEvent事件
protected:
void mousePressEvent(QMouseEvent* ev)override;
void mouseReleaseEvent(QMouseEvent* ev)override;
void mouseMoveEvent(QMouseEvent* ev)override;
.h文件
namespace {
/* 这里我们将一个窗口划分为9个区域,分别为
左上角(1, 1)、中上(1,2)、右上角(1, 3)
左中 (2, 1)、 中间(2, 2)、右中 (2, 3)
左下角(3, 1)、中下(3,2)、 右下角(3, 3)*/
const int kMouseRegionLeft = 5;
const int kMouseRegionTop = 5;
const int kMouseRegionRight = 5;
const int kMouseRegionBottom = 5;
}
// 鼠标的 活动范围的 枚举
enum MousePosition
{
// 这个是上面图片划分的区域 1,1 区 就用 11 代表 , 1,2 就用12 代表 以此类推
kMousePositionLeftTop = 11,
kMousePositionTop = 12,
kMousePositionRightTop = 13,
kMousePositionLeft = 21,
kMousePositionMid = 22,
kMousePositionRight = 23,
kMousePositionLeftBottom = 31,
kMousePositionBottom = 32,
kMousePositionRightBottom = 33,
};
private:
//根据鼠标的设置鼠标样式,用于拉伸
void SetMouseCursor(int x, int y);
//判断鼠标的区域,用于拉伸
int GetMouseRegion(int x, int y);
private:
bool isPress;
QPoint windowsLastPs;
QPoint mousePs;
int mouse_press_region = kMousePositionMid;
.cpp文件
void SPlay::mousePressEvent(QMouseEvent* ev)
{
if (ev->button() == Qt::LeftButton) {
// 如果是鼠标左键
// 获取当前窗口位置,以窗口左上角
windowsLastPs = pos();
// 获取鼠标在屏幕的位置 就是全局的坐标 以屏幕左上角为坐标系
mousePs = ev->globalPos();
isPress = true;
// 获取鼠标在那个区域
mouse_press_region = GetMouseRegion(ev->pos().x(), ev->pos().y());
}
}
void SPlay::mouseReleaseEvent(QMouseEvent* ev)
{
if (ev->button() == Qt::LeftButton) {
isPress = false;
}
setCursor(QCursor{});
}
void SPlay::mouseMoveEvent(QMouseEvent* ev)
{
// 设置鼠标的形状
SetMouseCursor(ev->pos().x(), ev->pos().y());
// 计算的鼠标移动偏移量, 就是鼠标全局坐标 - 减去点击时鼠标坐标
QPoint point_offset = ev->globalPos() - mousePs;
if ((ev->buttons() == Qt::LeftButton) && isPress)
{
if (mouse_press_region == kMousePositionMid)
{
// 如果鼠标是在窗口的中间位置,就是移动窗口
move(windowsLastPs + point_offset);
}
else {
// 其他部分 是拉伸窗口
// 获取客户区
QRect rect = geometry();
switch (mouse_press_region)
{
// 左上角
case kMousePositionLeftTop:
rect.setTopLeft(rect.topLeft() + point_offset);
break;
case kMousePositionTop:
rect.setTop(rect.top() + point_offset.y());
break;
case kMousePositionRightTop:
rect.setTopRight(rect.topRight() + point_offset);
break;
case kMousePositionRight:
rect.setRight(rect.right() + point_offset.x());
break;
case kMousePositionRightBottom:
rect.setBottomRight(rect.bottomRight() + point_offset);
break;
case kMousePositionBottom:
rect.setBottom(rect.bottom() + point_offset.y());
break;
case kMousePositionLeftBottom:
rect.setBottomLeft(rect.bottomLeft() + point_offset);
break;
case kMousePositionLeft:
rect.setLeft(rect.left() + point_offset.x());
break;
default:
break;
}
setGeometry(rect);
mousePs = ev->globalPos();
}
}
}
void SPlay::SetMouseCursor(int x, int y)
{
// 鼠标形状对象
Qt::CursorShape cursor{};
int region = GetMouseRegion(x, y);
switch (region)
{
case kMousePositionLeftTop:
case kMousePositionRightBottom:
cursor = Qt::SizeFDiagCursor; break;
case kMousePositionRightTop:
case kMousePositionLeftBottom:
cursor = Qt::SizeBDiagCursor; break;
case kMousePositionLeft:
case kMousePositionRight:
cursor = Qt::SizeHorCursor; break;
case kMousePositionTop:
case kMousePositionBottom:
cursor = Qt::SizeVerCursor; break;
case kMousePositionMid:
cursor = Qt::ArrowCursor; break;
default:
break;
}
setCursor(cursor);
}
int SPlay::GetMouseRegion(int x, int y)
{
int region_x = 0, region_y = 0;
// 鼠标的X坐标小于 边界5 说明他在最上层区域 第一区域
if (x < kMouseRegionLeft)
{
region_x = 1;
}
else if (x > (this->width()/*窗体宽度*/ - kMouseRegionRight/*边界宽度5*/)) {
// 如果鼠标X坐标 大于 最右侧的边界 说明他在第三区域
region_x = 3;
}
else {
region_x = 2;
}
if (y < kMouseRegionTop)
{
// 同理 鼠标Y坐标 小于上层边界5 说明鼠标在第一区域
region_y = 1;
}
else if (y > (this->height() - kMouseRegionBottom)) {
// 鼠标Y坐标的 大于 最下面的坐标,鼠标就在 第三区
region_y = 3;
}
else {
region_y = 2;
}
// 最后计算 表示区域的 数值 (x=1, y=1) 计算 = 1*10+1 =11
// x=2,y=3 = 3*10+2 = 32 在图的 3,2 区域
return region_y * 10 + region_x;
}
2.QSizeGrip实现
#include <QApplication>
#include <QWidget>
#include <QVBoxLayout>
#include <QSizeGrip>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QWidget *widget = new QWidget;
QVBoxLayout *layout = new QVBoxLayout(widget);
widget->setLayout(layout);
// 添加窗口内容
// ...
// 添加 QSizeGrip 控件
QSizeGrip *sizeGrip = new QSizeGrip(widget);
layout->addWidget(sizeGrip, 0, Qt::AlignBottom | Qt::AlignRight);
// 设置窗口大小和位置
widget->resize(400, 300);
widget->move(100, 100);
widget->show();
return app.exec();
}
在这个示例中,我们首先创建一个QWidget对象和一个QVBoxLayout布局对象,并将布局设置为窗口的布局。然后,我们添加窗口的内容到布局中。
接下来,我们创建一个QSizeGrip对象,并将其添加到布局中的右下角。我们使用Qt::AlignBottom | Qt::AlignRight参数将QSizeGrip控件放置在窗口的右下角。
最后,我们设置窗口的大小和位置,并将其显示出来。
通过在无边框窗口中添加QSizeGrip控件,用户可以使用鼠标拖动控件来调整窗口的大小。
参考文章1:QT 创建一个 可移动、可拉伸的无边框窗体_qt 无边框窗口拉伸-CSDN博客
参考文章2:Qt实现无边框窗口实现拉伸的三种方法--附源码_qt 无边框窗口拉伸-CSDN博客
参考小项目:https://github.com/a-mo-xi-wei/frameLessWindow
标签:case,鼠标,缩放,拖动,int,ev,rect,Qt From: https://blog.csdn.net/m0_74091159/article/details/141069966