赞
踩
简单说一下实现的功能,如下图,在主窗口中有一个绿色的子窗口。Qt的自带属性,可以实现鼠标移动到蓝色主窗口边缘时改变鼠标形态,拖动鼠标改变主窗口的大小。现在任务是将中间的绿色子窗口也处理成带这种属性的窗口。
此文章是在借鉴了https://blog.csdn.net/qq_16952303/article/details/51974502?utm_medium=distribute.pc_relevant_bbs_down.none-task-blog-baidujs-1.nonecase&depth_1-utm_source=distribute.pc_relevant_bbs_down.none-task-blog-baidujs-1.nonecase的基础上进行改造实现的。
以下是中间绿色子窗口的代码:
#ifndef DRAGRESIZEWGT_H #define DRAGRESIZEWGT_H #include <QWidget> #include <QMouseEvent> #include <QPoint> namespace Ui { class DragResizeWgt; } class DragResizeWgt : public QWidget { Q_OBJECT public: explicit DragResizeWgt(QWidget *parent = nullptr); ~DragResizeWgt(); public: void mousePressEvent(QMouseEvent *event); void mouseMoveEvent(QMouseEvent *event); void mouseReleaseEvent(QMouseEvent *event); private: void checkEdge(); private: Ui::DragResizeWgt *ui; QPoint m_startCursor; int m_nLeftOff = 0;//鼠标开始拖拽时子窗口左边相对父窗口左边的距离 int m_nRightOff = 0;//鼠标开始拖拽时子窗口右边相对父窗口左边的距离 int m_nTopOff = 0;//鼠标开始拖拽时子窗口上边相对父窗口上边的距离 int m_nBottomOff = 0;//鼠标开始拖拽时子窗口下边相对父窗口上边的距离 QPoint dragPosition; //鼠标拖动的位置 int edgeMargin = 4; //鼠标检测的边缘距离 enum { nodir, top = 0x01, bottom = 0x02, left = 0x04, right = 0x08, topLeft = 0x01 | 0x04, topRight = 0x01 | 0x08, bottomLeft = 0x02 | 0x04, bottomRight = 0x02 | 0x08} resizeDir; //更改尺寸的方向 }; #endif // DRAGRESIZEWGT_H
#include "DragResizeWgt.h" #include "ui_DragResizeWgt.h" #include <QDebug> #include "Windows.h" #include <QMouseEvent> #include <QObject> #include <QWidget> #define min(a,b) ((a)<(b)? (a) :(b)) #define max(a,b) ((a)>(b)? (a) :(b)) DragResizeWgt::DragResizeWgt(QWidget *parent) : QWidget(parent), ui(new Ui::DragResizeWgt) { ui->setupUi(this); this->setObjectName("DragResizeWgt"); //注意:一定要设置一个最小的宽高奥,要不会被拖到看不见,默认最小(0,0) setMinimumSize(QSize(1,1)); //一定一定要有这句话奥,这是能捕捉到这个窗口鼠标事件的关键,还有一点需要特别注意,如果这个窗口上会叠加其他的widget或者控件,对应的子UI也需要调用setMouseTracking这个函数 this->setMouseTracking(true); this->setWindowFlags(Qt::FramelessWindowHint); edgeMargin = 4; //设置检测边缘为4 resizeDir = nodir; //初始化检测方向为无 } DragResizeWgt::~DragResizeWgt() { delete ui; } void DragResizeWgt::mousePressEvent(QMouseEvent *event) { event->ignore(); if (event->button() == Qt::LeftButton) //每当按下鼠标左键就记录一下位置 { dragPosition = event->globalPos() - frameGeometry().topLeft(); //获得鼠标按键位置相对窗口左上面的位置 m_startCursor = event->globalPos(); m_nLeftOff = frameGeometry().left(); m_nRightOff = frameGeometry().right(); m_nTopOff = frameGeometry().top(); m_nBottomOff = frameGeometry().bottom(); } } void DragResizeWgt::mouseMoveEvent(QMouseEvent *event) { event->ignore(); if (event->buttons() & Qt::LeftButton)//如果左键是按下的 { if(resizeDir == nodir)//鼠标未放置在边缘处,进行窗口整体拖动处理 { move(event->globalPos() - dragPosition); } else//拖拽边缘,根据拖拽方向进行大小调整 { int ptop,pbottom,pleft,pright; ptop = m_nTopOff; pbottom = m_nBottomOff; pleft = m_nLeftOff; pright = m_nRightOff; if(resizeDir & top)//拖拽顶部上下变化 { //计算根据当前鼠标位置与拖拽偏移量计算当前top的位置 ptop = m_nTopOff-(m_startCursor.ry()- event->globalY()); if(this->height() <= minimumHeight())//进行极端高度最小的处理 { ptop = min(m_nBottomOff-minimumHeight(),ptop); } else if(this->height() >= maximumHeight())//进行极端高度最大的处理 { ptop = max(m_nBottomOff-maximumHeight(),ptop); } } else if(resizeDir & bottom)//拖拽底部上下变化 { //计算根据当前鼠标位置与拖拽偏移量计算当前bottom的位置 pbottom = m_nBottomOff +(event->globalY()-m_startCursor.ry()); if(this->height()<minimumHeight())//进行极端高度最小的处理 { pbottom = m_nTopOff+minimumHeight(); } else if(this->height()>maximumHeight())//进行极端高度最大的处理 { pbottom = m_nTopOff+maximumHeight(); } } if(resizeDir & left)//拖拽左侧左右变化 { //计算根据当前鼠标位置与拖拽偏移量计算当前left的位置 pleft = m_nLeftOff-(m_startCursor.rx() - event->globalX()); if(this->width()<= minimumWidth())//进行极端宽度最小的处理 { pleft = min(pleft,m_nRightOff- minimumWidth()); } else if(this->width() >= maximumWidth())//进行极端宽度最大的处理 { pleft = max(m_nRightOff- maximumWidth(),pleft); } } else if(resizeDir & right)//拖拽右侧左右变化 { //计算根据当前鼠标位置与拖拽偏移量计算当前right的位置 pright = m_nRightOff + (event->globalX()-m_startCursor.rx()); if(this->width()<minimumWidth())//进行极端宽度最小的处理 { pright = m_nLeftOff+minimumWidth(); } else if(this->width()> this->maximumWidth())//进行极端宽度最大的处理 { pright = m_nLeftOff + this->maximumWidth(); } } setGeometry(pleft,ptop,pright-pleft,pbottom-ptop); } } else checkEdge(); } void DragResizeWgt::mouseReleaseEvent(QMouseEvent * event) { event->ignore(); if(resizeDir != nodir)//还原鼠标样式 { checkEdge(); } } void DragResizeWgt::checkEdge() { QPoint pos = this->mapFromGlobal(QCursor::pos());//开始拖拽时点击控件的什么位置 int diffLeft = pos.rx(); int diffRight = this->width() - diffLeft; int diffTop = pos.ry(); int diffBottom = this->height()- diffTop; QCursor tempCursor; //获得当前鼠标样式,注意:只能获得当前鼠标样式然后再重新设置鼠标样式 tempCursor = cursor(); //因为获得的不是鼠标指针,所以不能这样用:cursor().setXXXXX if(diffTop < edgeMargin) { //根据 边缘距离 分类改变尺寸的方向 if(diffLeft < edgeMargin) { resizeDir = topLeft; tempCursor.setShape(Qt::SizeFDiagCursor); } else if(diffRight < edgeMargin) { resizeDir = topRight; tempCursor.setShape(Qt::SizeBDiagCursor); } else { resizeDir = top; tempCursor.setShape(Qt::SizeVerCursor); } } else if(diffBottom < edgeMargin) { if(diffLeft < edgeMargin) { resizeDir = bottomLeft; tempCursor.setShape(Qt::SizeBDiagCursor); } else if(diffRight < edgeMargin) { resizeDir = bottomRight; tempCursor.setShape(Qt::SizeFDiagCursor); } else { resizeDir = bottom; tempCursor.setShape(Qt::SizeVerCursor); } } else if(diffLeft < edgeMargin) { resizeDir = left; tempCursor.setShape(Qt::SizeHorCursor); } else if(diffRight < edgeMargin) { resizeDir = right; tempCursor.setShape(Qt::SizeHorCursor); } else { resizeDir = nodir; tempCursor.setShape(Qt::ArrowCursor); } setCursor(tempCursor); }
以下是在蓝色父窗口中的使用
DragResizeWgt* m_dragWgt = new DragResizeWgt(this);
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。