qt实现去掉边框后的窗口移动、拉伸和靠边界隐藏

QT实现窗口去掉边框后的移动、拉伸和窗口隐藏

窗口移动和拉伸的思路

通过重写mousemove函数实现窗口的移动,但是在项目中不可能对每一个模块都进行函数重写,通过使用事件滤波器(eventfilter)来解决这个问题,在事件滤波器中判断事件类型,然后进行相应操作,窗口移动思想是当检测到事件为鼠标移动事件后通过move函数将窗口移动相应的dx和dy距离;窗口拉伸的思路是:仿照QSizeGrip类中源码的思想。先将窗口进行大小的改变,为了保持对边不变(即你移动某一个边时,另一个边要保持不变),将对边移动到原来的位置。

代码实现

qgrip.h/
#ifndef QGRIP_H
#define QGRIP_H

#include 
#include
#include
#include

QT_BEGIN_NAMESPACE
enum ResizeRegion
{
    Default,
    North,
    NorthEast,
    East,
    SouthEast,
    South,
    SouthWest,
    West,
    NorthWest,
    Arrow
};
enum EdgeStatus{
    Eg_normal,
    Eg_top,
    Eg_left,
    Eg_right,
    Eg_bottom


};
class  QGrip : public QWidget
{
    Q_OBJECT
public:
     QGrip(QWidget *parent);
    ~QGrip();
    void updateTopLevelWidget();
    ResizeRegion resizeregion;
    QPoint p;
    QPoint dragPos;
    QRect r;
    int d;
    Qt::Corner m_corner;
    Qt::Edge m_edge;
    int resizeBorderWidth=10;
    Qt::Corner corner(QWidget*q,QMouseEvent*qe) const;
    Qt::Edge edge()const; 
    void hideWidget(QWidget*q,EdgeStatus es);//窗口隐藏
    void showWidget(QWidget*q,EdgeStatus es);//窗口显示
    EdgeStatus isDirection(QWidget *q);//判断窗口位置状态


protected:
    void paintEvent(QWidget*o,QPaintEvent *event,Qt::Corner m_corner);
    bool eventFilter(QObject *o, QEvent *e) Q_DECL_OVERRIDE;
    void setResizeCursor(QWidget*w,ResizeRegion region);
    ResizeRegion getResizeRegion(QWidget*w,QPoint clientPos);
private:
    EdgeStatus m_edgeStatus;
    int show_edgeWidth=8;
    QPoint inialPos;
    QPoint mousePos;
    QPoint mousePos2;

};


QT_END_NAMESPACE

#endif // QGRIP_H
//////////////////
qgrip.cpp
#include"qgrip.h"
#include<QPainter>
#include<QStyle>
#include<QStyleOption>
#include
#include<QDesktopWidget>
#include<QLayout>
#include<QApplication>
#include
 QWidget *qt_sizegrip_topLevelWidget(QWidget* w)
    {
        while (w && !w->isWindow() && w->windowType() != Qt::SubWindow)
            w = w->parentWidget();
        return w;
    }
void QGrip::paintEvent(QWidget*o,QPaintEvent *event,Qt::Corner m_corner)
{
    QPainter painter(o);
    QStyleOptionSizeGrip opt;
    opt.init(o);
    opt.corner=m_corner;
    style()->drawControl(QStyle::CE_SizeGrip, &opt, &painter, o);

}

bool QGrip::eventFilter(QObject *o, QEvent *e)
{
    QRect availableGeometry;
    QWidget*oo=static_cast<QWidget*>(o);
    QMouseEvent*ee=static_cast<QMouseEvent*>(e);
    QPaintEvent*qp=static_cast<QPaintEvent*>(e);

    m_edgeStatus=isDirection(oo);
    if(ee->type()==QEvent::Leave){
        hideWidget(oo,m_edgeStatus);
    }
    if(ee->type()==QEvent::Enter){
        showWidget(oo,m_edgeStatus);
    }
//    if(ee->type()==QEvent::Move){
//        QDesktopWidget*deskwidget=QApplication::desktop();
//        if(oo->pos().x()>(-oo->frameGeometry().width()/2)&&(oo->pos().x()<(deskwidget->width()-oo->frameGeometry().width()/2))&&(oo->pos().y()>(-oo->frameGeometry().height()/2))){
//        inialPos.rx()=oo->pos().x();
//        inialPos.ry()=oo->pos().y();
//        }

//    }

 if (e->type()==QEvent::MouseButtonPress&&ee->button() == Qt::LeftButton){//左键按下
     this->p=ee->globalPos();//p获得整体坐标
     this->r=oo->geometry();//r获得矩形坐标(包括宽高和x、y)
     this->dragPos=ee->pos();//ee获得光标点击处的位置
     resizeregion = getResizeRegion(oo,dragPos);//获得光标要移动的方向
     setResizeCursor(oo,resizeregion);//将光标变为对应的箭头
 }
  if(e->type()==QEvent::MouseMove){//光标移动
  QWidget*tlw=qt_sizegrip_topLevelWidget(oo);//定位到顶级窗口
  QPoint np(ee->globalPos());//np储存光标移动后的整体坐标
  QPoint clientCursorPos=ee->pos();//光标移动后的相对窗体的坐标
  QRect qr=oo->rect();
  QSize ns;

  QRect resizeInnerRect(resizeBorderWidth, resizeBorderWidth, r.width() - 2*resizeBorderWidth, r.height() - 2*resizeBorderWidth);//判断是否移动
if(qr.contains(clientCursorPos) && resizeInnerRect.contains(clientCursorPos)){//属于移动
    if ((ee->buttons() & Qt::LeftButton)) {
        oo->move(ee->globalPos() - dragPos);
}
}
else{
if(resizeregion==NorthWest||resizeregion==NorthEast){ns.rheight()=r.height()-(np.y()-p.y());}//设置角
else if(resizeregion==SouthWest||resizeregion==SouthEast){ns.rheight()=r.height()+(np.y()-p.y());}
if(resizeregion==NorthWest||resizeregion==SouthWest){ns.rwidth()=r.width()-(np.x()-p.x());}
else if(resizeregion==NorthEast||resizeregion==SouthEast){ns.rwidth()=r.width()+(np.x()-p.x());}

else if(resizeregion==North){ns.rheight()=r.height()-(np.y()-p.y());ns.rwidth()=r.width();}//设置边
else if(resizeregion==South){ns.rheight()=r.height()+(np.y()-p.y());ns.rwidth()=r.width();}
else if(resizeregion==West){ns.rwidth()=r.width()-(np.x()-p.x());ns.rheight()=r.height();}
else if(resizeregion==East){ns.rwidth()=r.width()+(np.x()-p.x());ns.rheight()=r.height();}

ns = QLayout::closestAcceptableSize(tlw, ns);
QPoint p;
QRect nr(p, ns);
if(resizeregion==NorthWest){nr.moveBottomRight(r.bottomRight());}//设置角
if(resizeregion==NorthEast){nr.moveBottomLeft(r.bottomLeft());}
if(resizeregion==SouthWest){nr.moveTopRight(r.topRight());}
if(resizeregion==SouthEast){nr.moveTopLeft(r.topLeft());}

if(resizeregion==North){nr.moveBottom(r.bottom());nr.moveBottomRight(r.bottomRight());nr.moveBottomLeft(r.bottomLeft());}//设置边
if(resizeregion==South){nr.moveTop(r.top());nr.moveTopRight(r.topRight());nr.moveTopLeft(r.topLeft());}
if(resizeregion==West){nr.moveRight(r.right());nr.moveBottomRight(r.bottomRight());nr.moveTopRight(r.topRight());}
if(resizeregion==East){nr.moveLeft(r.left());nr.moveBottomLeft(r.bottomLeft());nr.moveTopLeft(r.topLeft());}

 tlw->setGeometry(nr);
  }
  }
//  else if(qr.contains(clientCursorPos) && resizeInnerRect.contains(clientCursorPos)){
 // }
  if (e->type()==QEvent::MouseButtonRelease){
       oo->setCursor(Qt::ArrowCursor);
}//鼠标松开
}

void QGrip::setResizeCursor(QWidget *w, ResizeRegion region)
{
    switch (region)
    {
    case North:
    case South:
        w->setCursor(Qt::SizeVerCursor);//设置光标为垂直双箭头
        break;
    case East:
    case West:
        w->setCursor(Qt::SizeHorCursor);
        break;
    case NorthWest:
    case SouthEast:
        w->setCursor(Qt::SizeFDiagCursor);
        break;
    case NorthEast:
    case SouthWest:
         w->setCursor(Qt::SizeBDiagCursor);
         break;
    case Arrow:
        w->setCursor(Qt::ArrowCursor);
        break;
    default:
        w->setCursor(Qt::ArrowCursor);
        break;
    }
}

ResizeRegion QGrip::getResizeRegion(QWidget *w, QPoint clientPos)
{
    if (clientPos.y() <= resizeBorderWidth) {
        if (clientPos.x() <= resizeBorderWidth){
            return NorthWest;}
        else if (clientPos.x() >= (w->width() - resizeBorderWidth))
            return NorthEast;
        else
            return North;
    }
    else if (clientPos.y() >=(w->height() - resizeBorderWidth)) {
        if (clientPos.x() <= resizeBorderWidth)
            return SouthWest;
        else if (clientPos.x() >= (w->width() - resizeBorderWidth))
            return SouthEast;
        else
            return South;
    }

        else if (clientPos.x() <= resizeBorderWidth)
            return West;
        else if(clientPos.x() >=(w->width() - resizeBorderWidth))
            return East;

    else
        return Arrow;
}
EdgeStatus QGrip::isDirection(QWidget *q)
{
    QDesktopWidget*deskwidget=QApplication::desktop();
    if(q->pos().y()<=show_edgeWidth) return Eg_top;
    else if(q->pos().x()<=show_edgeWidth) return Eg_left;
    else if(q->pos().x()>=(deskwidget->width()-q->frameGeometry().width()-show_edgeWidth)) return Eg_right;
    else
        return Eg_normal;
}
void QGrip::hideWidget(QWidget*q,EdgeStatus es)
{
    QDesktopWidget*deskwidget=QApplication::desktop();
    if(es==Eg_top){inialPos.rx()=q->pos().x(); inialPos.ry()=q->pos().y();Sleep(3*1000);q->move(q->pos().x(),show_edgeWidth-q->frameGeometry().height());}
    else if(es==Eg_left){inialPos.rx()=q->pos().x(); inialPos.ry()=q->pos().y();Sleep(3*1000);q->move(show_edgeWidth-q->frameGeometry().width(),q->pos().y());}
    else if(es==Eg_right){inialPos.rx()=q->pos().x(); inialPos.ry()=q->pos().y();Sleep(3*1000);q->move(deskwidget->width()-show_edgeWidth,q->pos().y());}
    else
        es==Eg_normal;
}
void QGrip::showWidget(QWidget *q,EdgeStatus es){
    if(es==Eg_top){q->move(inialPos.x(),inialPos.y());}
    else if(es==Eg_left){q->move(inialPos.x(),inialPos.y());}
    else if(es==Eg_right){q->move(inialPos.x(),inialPos.y());}
}

QGrip::QGrip(QWidget *parent):QWidget(parent){m_edgeStatus=Eg_normal;}
QGrip::~QGrip(){}
/////////////////
widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include"qgrip.h"
#include<QSizeGrip>

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    this->setWindowFlags(Qt::FramelessWindowHint);
  // QSizeGrip*q=new QSizeGrip(this);
   QGrip*q=new QGrip(this);
    this->installEventFilter(q);

}

Widget::~Widget()
{
    delete ui;
}

你可能感兴趣的:(QT)