Qt/C++ 无边框随意拖动改变大小(跨平台版)无BUG!!

一,心路:

    这个东西有点难弄,他不是技术性特别强的,主要是繁琐的枚举各种条件发生的情况,网上有可以用的!但无奈只能windows使用,使用nativeEvent(~,~,~),有跨平台的也是N个BUG,难得修复啊~那就自己造呗,经过测试无bug,下面我就上源码~源码下有可以下载的

二,源码部分:

.h文件

#ifndef ABSFRAMELESSAUTOSIZE_H
#define ABSFRAMELESSAUTOSIZE_H


#include
#include
enum CursorPos{Default,Right,Left,Bottom,Top,TopRight,TopLeft,BottomRight,BottomLeft};
struct pressWindowsState
{
    bool    MousePressed;
    bool   IsPressBorder;
    QPoint  MousePos;
    QPoint  WindowPos;
    QSize PressedSize;
};


class AbsFrameLessAutoSize : public QWidget
{
    Q_OBJECT


public:
    AbsFrameLessAutoSize(QWidget *parent = 0);
    ~AbsFrameLessAutoSize(){}


     void mouseMoveRect(const QPoint &p);
protected:
    virtual void mousePressEvent(QMouseEvent *event);
    virtual void mouseReleaseEvent(QMouseEvent *event);
    virtual void mouseMoveEvent(QMouseEvent *event);


    pressWindowsState m_state;
    int m_border;
    CursorPos m_curPos;
};


#endif // ABSFRAMELESSAUTOSIZE_H

////////////////////////////////////////////////////////////////万恶的分界线

.cpp文件

#include "AbsFrameLessAutoSize.h"
#include
AbsFrameLessAutoSize::AbsFrameLessAutoSize(QWidget *parent)
    : QWidget(parent)
{
    m_border=4;
    m_state.MousePressed=false;
    setMinimumSize(400,550);
    setMaximumSize(800,700);


    setMouseTracking(true);
    setWindowFlags(Qt::FramelessWindowHint); //setting windows tool bar icon invisiable
    setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
}


void AbsFrameLessAutoSize::mouseMoveRect(const QPoint& p)
{
    if(!m_state.IsPressBorder)
    {
        if( p.x()>width()-m_border&&p.y()m_border)//right side
        {
            setCursor(Qt::SizeHorCursor);
            m_curPos= CursorPos::Right;
        }
        else if(p.x()m_border)//left side;
        {
            setCursor(Qt::SizeHorCursor);
            m_curPos= CursorPos::Left;
        }
        else if(p.y()>height()-m_border&&p.x()>m_border&&p.x()         {
            setCursor(Qt::SizeVerCursor);
            m_curPos= CursorPos::Bottom;
        }
        else if(p.y()m_border&&p.x()         {
            setCursor(Qt::SizeVerCursor);
            m_curPos=CursorPos::Top;
        }
//corner
        else if(p.y()width()-m_border)
        {
            setCursor(Qt::SizeBDiagCursor);
            m_curPos=CursorPos::TopRight;
        }


        else if(p.y()         {
            setCursor(Qt::SizeFDiagCursor);
            m_curPos=CursorPos::TopLeft;
        }


        else if(p.x()>m_border&&p.y()>height()-m_border)
        {
            setCursor(Qt::SizeFDiagCursor);
            m_curPos=CursorPos::BottomRight;
        }


        else if(p.x()height()-m_border)
        {
            setCursor(Qt::SizeBDiagCursor);
            m_curPos=CursorPos::BottomLeft;
        }
////
        else
        {
            setCursor(Qt::ArrowCursor);
        }
    }
    else
    {
        switch (m_curPos) {
        case CursorPos::Right:
        {
           int setW=QCursor::pos().x()-x();
           if(minimumWidth()<=setW&&setW<=maximumWidth())
             setGeometry(x(),y(),setW,height());
            break;
        }
        case CursorPos::Left:
        {
            int setW=x()+width()-QCursor::pos().x();
            int setX=QCursor::pos().x();
            if(minimumWidth()<=setW&&setW<=maximumWidth())
              setGeometry(setX,y(),setW,height());
             break;
        }
        case CursorPos::Bottom:
        {
            int setH=QCursor::pos().y()-y();
            if(minimumHeight()<=setH&&setH<=maximumHeight())
            setGeometry(x(),y(),width(),setH);
            break;
        }
        case CursorPos::Top:
        {
           int setH=y()-QCursor::pos().y()+height();
           if(minimumHeight()<=setH&&setH<=maximumHeight())
             setGeometry(x(),QCursor::pos().y(),width(),setH);
             break;
        }
        case CursorPos::TopRight:
        {
            int setH=y()+height()-QCursor::pos().y();
            int setW=QCursor::pos().x()-x();
            int setY=QCursor::pos().y();
            if(setH>=maximumHeight())
            {
                setY=m_state.WindowPos.y()+m_state.PressedSize.height()-height();
                setH=maximumHeight();
            }
            if(setH<=minimumHeight())
            {
                setY=m_state.WindowPos.y()+m_state.PressedSize.height()-height();
                setH=minimumHeight();
            }
            setGeometry(m_state.WindowPos.x(),setY,setW,setH);
            break;
        }
        case CursorPos::TopLeft:
        {
            int setY=QCursor::pos().y();
            int setX=QCursor::pos().x();


            int setW=pos().x()+width()-setX;
            int setH=pos().y()+height()-setY;
            int totalW= m_state.WindowPos.x()+m_state.PressedSize.width();
            int totalH=m_state.WindowPos.y()+m_state.PressedSize.height();


            if(totalW-setX>=maximumWidth())
            {
                setX=totalW-maximumWidth();
                setW=maximumWidth();
            }
            if(totalW-setX<=minimumWidth())
            {
                setX=totalW-minimumWidth();
                setW=minimumWidth();
            }
            if(totalH-setY>=maximumHeight())
            {
                setY=totalH-maximumHeight();
                setH=maximumHeight();
            }
            if(totalH-setY<=minimumHeight())
            {
                setY=totalH-minimumHeight();
                setH=minimumHeight();
            }
            setGeometry(setX,setY,setW,setH);
            break;
        }
        case CursorPos::BottomRight:
        {
           int setW=QCursor::pos().x()-x();
           int setH=QCursor::pos().y()-y();
           setGeometry(m_state.WindowPos.x(),m_state.WindowPos.y(),setW,setH);
             break;
        }
        case CursorPos::BottomLeft:
        {
            int setW=x()+width()-QCursor::pos().x();
            int setH=QCursor::pos().y()-m_state.WindowPos.y();
            int setX=QCursor::pos().x();
            int totalW= m_state.WindowPos.x()+m_state.PressedSize.width();
            if(totalW-setX>=maximumWidth())
            {
                setX=totalW-maximumWidth();
                setW=maximumWidth();
            }
            if(totalW-setX<=minimumWidth())
            {
                setX=totalW-minimumWidth();
                setW=minimumWidth();
            }
            setGeometry(setX,m_state.WindowPos.y(),setW,setH);
            break;
        }
        default:
            break;
        }
    }
}
void AbsFrameLessAutoSize::mousePressEvent(QMouseEvent *event)
{
    m_state.PressedSize=this->size();
    m_state.IsPressBorder=false;
      setFocus();
      if (event->button() == Qt::LeftButton)
     {
          m_state.WindowPos = this->pos(); //save the prssed position
          if(QRect(m_border+1,m_border+1,width()-(m_border+1)*2,height()-(m_border+1)*2).contains(event->pos()))
          {
              m_state.MousePos = event->globalPos();
              m_state.MousePressed = true;
          }
          else
              m_state.IsPressBorder=true;
      }
}
void AbsFrameLessAutoSize::mouseMoveEvent(QMouseEvent *event)
{
    mouseMoveRect(mapFromGlobal(QCursor::pos()));
    if (m_state.MousePressed)
        {
            this->move(m_state.WindowPos + (event->globalPos() - m_state.MousePos));
        }


}
void AbsFrameLessAutoSize::mouseReleaseEvent(QMouseEvent *event)
{
      m_state.IsPressBorder=false;
    if (event->button() == Qt::LeftButton)
    {
        this->m_state.MousePressed = false;
    }
}

三,源码下载

下载链接:http://download.csdn.net/detail/what951006/9655285


powered by:小乌龟在大乌龟背上

更多文章:http://blog.csdn.net/what951006

你可能感兴趣的:(Qt项目实现技术记录)