## 一、前言

相信各位CS结构开发的程序员,多多少少都遇到过需要美化界面的事情,一般都不会采用系统的标题栏,这样就需要无边框标题栏窗体,默认的话无边框的标题栏都不支持拉伸和拖动的,毕竟去掉了标题栏则意味着失去了系统的窗体的属性,拉伸和拖动都需要自己写代码去实现,网上有很多类似的开源的方案,我也看过不少,总体来说复杂了些,对于初学者来说有可能看的云里雾里的,比如边框四周八个方位都可以自由拉伸这块,我的思路是针对设定的八个方位的区域进行识别鼠标是否按下,按下的哪个部位则执行什么拉伸策略,鼠标移到哪个位置则对应改变鼠标指针形状,更浅显易懂一些,至于拖动移动,还可以设置拖动的标题栏的高度等。

主要功能:

1. 可以指定需要无边框的widget

2. 边框四周八个方位都可以自由拉伸

3. 可设置对应位置的边距,以便识别更大区域

4. 可设置是否允许拖动

5. 可设置是否允许拉伸

## 二、代码思路

bool FramelessWidget::eventFilter(QObject *watched, QEvent *event){    if (widget != 0 && watched == widget) {        if (event->type() == QEvent::Resize) {            //重新计算八个描点的区域,描点区域的作用还有就是计算鼠标坐标是否在某一个区域内            int width = widget->width();            int height = widget->height();            //左侧描点区域            rectLeft = QRect(0, padding, padding, height - padding * 2);            //上侧描点区域            rectTop = QRect(padding, 0, width - padding * 2, padding);            //右侧描点区域            rectRight = QRect(width - padding, padding, padding, height - padding * 2);            //下侧描点区域            rectBottom = QRect(padding, height - padding, width - padding * 2, padding);            //左上角描点区域            rectLeftTop = QRect(0, 0, padding, padding);            //右上角描点区域            rectRightTop = QRect(width - padding, 0, padding, padding);            //左下角描点区域            rectLeftBottom = QRect(0, height - padding, padding, padding);            //右下角描点区域            rectRightBottom = QRect(width - padding, height - padding, padding, padding);        } else if (event->type() == QEvent::HoverMove) {            //设置对应鼠标形状,这个必须放在这里而不是下面,因为可以在鼠标没有按下的时候识别            QHoverEvent *hoverEvent = (QHoverEvent *)event;            QPoint point = hoverEvent->pos();            if (resizeEnable) {                if (rectLeft.contains(point)) {                    widget->setCursor(Qt::SizeHorCursor);                } else if (rectRight.contains(point)) {                    widget->setCursor(Qt::SizeHorCursor);                } else if (rectTop.contains(point)) {                    widget->setCursor(Qt::SizeVerCursor);                } else if (rectBottom.contains(point)) {                    widget->setCursor(Qt::SizeVerCursor);                } else if (rectLeftTop.contains(point)) {                    widget->setCursor(Qt::SizeFDiagCursor);                } else if (rectRightTop.contains(point)) {                    widget->setCursor(Qt::SizeBDiagCursor);                } else if (rectLeftBottom.contains(point)) {                    widget->setCursor(Qt::SizeBDiagCursor);                } else if (rectRightBottom.contains(point)) {                    widget->setCursor(Qt::SizeFDiagCursor);                } else {                    widget->setCursor(Qt::ArrowCursor);                }            }            //根据当前鼠标位置,计算XY轴移动了多少            int offsetX = point.x() - lastPos.x();            int offsetY = point.y() - lastPos.y();            //根据按下处的位置判断是否是移动控件还是拉伸控件            if (moveEnable) {                if (pressed) {                    widget->move(widget->x() + offsetX, widget->y() + offsetY);                }            }            if (resizeEnable) {                if (pressedLeft) {                    int resizeW = widget->width() - offsetX;                    if (widget->minimumWidth() <= resizeW) {                        widget->setGeometry(widget->x() + offsetX, rectY, resizeW, rectH);                    }                } else if (pressedRight) {                    widget->setGeometry(rectX, rectY, rectW + offsetX, rectH);                } else if (pressedTop) {                    int resizeH = widget->height() - offsetY;                    if (widget->minimumHeight() <= resizeH) {                        widget->setGeometry(rectX, widget->y() + offsetY, rectW, resizeH);                    }                } else if (pressedBottom) {                    widget->setGeometry(rectX, rectY, rectW, rectH + offsetY);                } else if (pressedLeftTop) {                    int resizeW = widget->width() - offsetX;                    int resizeH = widget->height() - offsetY;                    if (widget->minimumWidth() <= resizeW) {                        widget->setGeometry(widget->x() + offsetX, widget->y(), resizeW, resizeH);                    }                    if (widget->minimumHeight() <= resizeH) {                        widget->setGeometry(widget->x(), widget->y() + offsetY, resizeW, resizeH);                    }                } else if (pressedRightTop) {                    int resizeW = rectW + offsetX;                    int resizeH = widget->height() - offsetY;                    if (widget->minimumHeight() <= resizeH) {                        widget->setGeometry(widget->x(), widget->y() + offsetY, resizeW, resizeH);                    }                } else if (pressedLeftBottom) {                    int resizeW = widget->width() - offsetX;                    int resizeH = rectH + offsetY;                    if (widget->minimumWidth() <= resizeW) {                        widget->setGeometry(widget->x() + offsetX, widget->y(), resizeW, resizeH);                    }                    if (widget->minimumHeight() <= resizeH) {                        widget->setGeometry(widget->x(), widget->y(), resizeW, resizeH);                    }                } else if (pressedRightBottom) {                    int resizeW = rectW + offsetX;                    int resizeH = rectH + offsetY;                    widget->setGeometry(widget->x(), widget->y(), resizeW, resizeH);                }            }        } else if (event->type() == QEvent::MouseButtonPress) {            //记住当前控件坐标和宽高以及鼠标按下的坐标            QMouseEvent *mouseEvent = (QMouseEvent *)event;            rectX = widget->x();            rectY = widget->y();            rectW = widget->width();            rectH = widget->height();            lastPos = mouseEvent->pos();            //判断按下的手柄的区域位置            if (rectLeft.contains(lastPos)) {                pressedLeft = true;            } else if (rectRight.contains(lastPos)) {                pressedRight = true;            } else if (rectTop.contains(lastPos)) {                pressedTop = true;            } else if (rectBottom.contains(lastPos)) {                pressedBottom = true;            } else if (rectLeftTop.contains(lastPos)) {                pressedLeftTop = true;            } else if (rectRightTop.contains(lastPos)) {                pressedRightTop = true;            } else if (rectLeftBottom.contains(lastPos)) {                pressedLeftBottom = true;            } else if (rectRightBottom.contains(lastPos)) {                pressedRightBottom = true;            } else {                pressed = true;            }        } else if (event->type() == QEvent::MouseMove) {            //改成用HoverMove识别        } else if (event->type() == QEvent::MouseButtonRelease) {            //恢复所有            pressed = false;            pressedLeft = false;            pressedRight = false;            pressedTop = false;            pressedBottom = false;            pressedLeftTop = false;            pressedRightTop = false;            pressedLeftBottom = false;            pressedRightBottom = false;            widget->setCursor(Qt::ArrowCursor);        }    }    return QObject::eventFilter(watched, event);}

## 三、效果图

## 四、开源主页

**以上作品完整源码下载都在开源主页,会持续不断更新作品数量和质量,欢迎各位关注。**

1. 国内站点:[https://gitee.com/feiyangqingyun/QWidgetDemo](https://gitee.com/feiyangqingyun/QWidgetDemo)

2. 国际站点:[https://github.com/feiyangqingyun/QWidgetDemo](https://github.com/feiyangqingyun/QWidgetDemo)

3. 个人主页:[https://blog.csdn.net/feiyangqingyun](https://blog.csdn.net/feiyangqingyun)

4. 知乎主页:[https://www.zhihu.com/people/feiyangqingyun/](https://www.zhihu.com/people/feiyangqingyun/)

qt widget设置边框_Qt开源作品16-通用无边框拖动拉伸相关推荐

  1. qt设置圆形按钮_Qt开源作品25-电池电量控件

    一.前言 现在这个时代,智能手机不要太流行,满大街都是,甚至连爷爷奶奶级别的人都会用智能手机,本次要写的控件就是智能手机中的电池电量表示控件,采用纯painter绘制,其实也可以采用贴图,我估计大部分 ...

  2. qt设置边框颜色_Qt开源作品14-导航按钮控件

    ## 一.前言 导航按钮控件,主要用于各种漂亮精美的导航条,我们经常在web中看到导航条都非常精美,都是html+css+js实现的,还自带动画过度效果,Qt提供的qss其实也是无敌的,支持基本上所有 ...

  3. qt 进度条_Qt开源作品12-硬盘容量控件

    一.前言 磁盘容量统计控件,说白了,就是用来统计本地盘符占用的容量,包括但不限于已用空间.剩余空间.总大小.已用百分比等,其中对应的百分比采用进度条显示,该进度条的前景色和背景色及文字颜色可以设置,在 ...

  4. qt 定时器_Qt开源作品23-颜色拾取器

    ## 一.前言 在做很多项目的UI界面的时候,相信绝大部分人都有过抄袭别人的UI界面尤其是颜色的时候,毕竟十个程序员九个没有审美,或者说审美跟一坨屎一样,大家主要的精力以及擅长点都是在写功能实现具体功 ...

  5. qt 在qtextedit显示数组_Qt开源作品34-qwt无需插件源码

    一.前言 QWT,全称是Qt Widgets for Technical Applications,是一个基于LGPL版权协议的开源项目,可生成各种统计图.为具有技术专业背景的程序提供GUI组件和一组 ...

  6. qt运行时间越长越卡_Qt开源作品22-运行时间记录类

    一.前言 在早期开发的软件中,尤其是初学者入门者写的软件,软件运行久了,难免遇到意外崩溃的时候,可是大部分的运行设备可能在现场客户那,需要记住每一次从软件启动后到软件意外关闭前的运行时间,需要记录的信 ...

  7. python写网络调试助手_Qt开源作品4-网络调试助手

    ## 一.前言 网络调试助手和串口调试助手是一对的,用Qt开发项目与硬件通信绝大部分都是要么串口通信(RS232 RS485 Modbus等),要么就是网络通信(TCP UDP HTTP等),所以一旦 ...

  8. qt 全屏窗口有边框_如何在全屏无边框窗口模式下玩任何Windows游戏

    qt 全屏窗口有边框 If you're a regular PC gamer, you know that playing a game in full screen mode can someti ...

  9. python小技巧大应用--基础实用漂亮界面(无边框,圆角,可拖拽)

    这回要实现一个漂亮的基础界面,要具有如下特色: 无边框,圆角,漂亮的背景,可拖拽移动,具有最小化,关闭按钮,界面与代码分离,支持qss 先展示一下最后的效果: 那就开始工作吧: 1.通过Qt Desi ...

最新文章

  1. 梯度下降法求多元线性回归及Java实现
  2. Foundations of Qt Development 学习笔记 Part1 Tips1-50
  3. legend3---Homestead中Laravel项目502 Bad Gateway
  4. linux日志服务是哪个,『学了就忘』Linux日志管理 — 2.日志服务rsyslogd
  5. 词性标注与命名实体识别
  6. 关于一些常见智柜问题的分析及解决办法
  7. 深度学习二(Pytorch物体检测实战)
  8. sumif三个条件怎么填_Excel根据条件进行求和的几个常用函数公式!
  9. mysql拒绝访问root用户_Linux部署MySql数据库(超简单)
  10. 勇者斗恶龙UVa11292 - Dragon of Loowater
  11. 网友发来ifeng网址,打开后却是QQ空间,总提示QQ未登录?原来是一个阴险的诱骗网页...
  12. IE 9 beta 下载地址
  13. 计算机毕业设计ssm+vue基本微信小程序的购物商城系统
  14. 在virtual box虚拟机上下载sniffer pro
  15. html显示网上图片不显示不出来,网页图片显示不出来,教您网页不显示图片怎么办...
  16. 使用系统之家重装Windows系统——写给小白
  17. fabric.js学习
  18. 计算机毕业设计php+vue基于微信小程序的叽喳音乐播放小程序
  19. 因子分析模型(主成分解)、及与主成分分析模型的联系与区别(附详细案例)
  20. 用Python代码来下载任意指定网易云歌曲(超详细版)

热门文章

  1. php 查询 判断 语句,关于php的判断语句
  2. 第七节:Asp.Net Core内置日志记录
  3. XML序列之System.Xml.Serialization
  4. 机器人学 —— 机器人感知(Mapping)
  5. const char*p,char const*p,char *const p
  6. shell脚本实现菜单操作
  7. npm -S -D -g i 有什么区别
  8. 软件工程网络15个人阅读作业1
  9. select简易的二级联动
  10. Zabbix监控nginx status