700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > Qt开源作品16-通用无边框拖动拉伸

Qt开源作品16-通用无边框拖动拉伸

时间:2024-06-20 04:37:27

相关推荐

Qt开源作品16-通用无边框拖动拉伸

一、前言

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

主要功能:

可以指定需要无边框的widget边框四周八个方位都可以自由拉伸可设置对应位置的边距,以便识别更大区域可设置是否允许拖动可设置是否允许拉伸

二、代码思路

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);}

三、效果图

四、开源主页

以上作品完整源码下载都在开源主页,会持续不断更新作品数量和质量,欢迎各位关注。本开源项目已经成功升级到V2.0版本,分门别类,图文并茂,保你爽到爆。Qt开源武林秘籍开发经验,看完学完,20K起薪,没有找我!国内站点:/feiyangqingyun/QWidgetDemo国际站点:/feiyangqingyun/QWidgetDemo开源秘籍:/feiyangqingyun/qtkaifajingyan个人主页:https://qtchina./知乎主页:/people/feiyangqingyun/

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。