QT 封装无边框窗口基类

无边框窗口拖拽标题栏可移动,且限制窗口可移出屏幕的范围,布局最大化、最小化、关闭按钮,双击标题栏最大化,设置标题栏颜色,窗口背景颜色等功能。

使用方法:

其中类DragProxy来自:https://blog.csdn.net/frieryumao/article/details/98733836

AAA::AAA(FramelessWidget *parent) :
    FramelessWidget(parent),
    ui(new Ui::AAA)
{
    ui->setupUi(this);
    QDesktopWidget* desktop = QApplication::desktop();
    QRect availableWindRect = QRect(desktop->availableGeometry());
    this->setMinimumSize(availableWindRect.width()*0.7,availableWindRect.height()*0.7);
    this->setWindowState(Qt::WindowMaximized);    // 主窗口默认最大化
    this->ActivationDoubleClick(true);

    DragProxy* dragProxy = new DragProxy(this);
    dragProxy->SetBorderWidth(8, 8, 8, 8);

解决鼠标在窗口边缘样式不改变问题

在主窗口上放置任何子窗口,不要覆盖主窗口四周边缘线,要保留一个像素点空白位置,使得鼠标边缘检测时可改变鼠标样式,例如下:在主窗口顶部放置标题栏,标题栏位置为(0,1),标题栏顶部与主窗口距离一个像素点,当鼠标在主窗口顶部时,检测鼠标样式可改变。
m_tittleLabel->setGeometry(0,1,this->width(),BTNSIZE);

#ifndef FRAMELESSWIDGET_H
#define FRAMELESSWIDGET_H
/******************************************************************************
**FileName: 无边框窗口基类
**Function:
**          1:窗口无边框
**          2:可添加最大化,最小化,关闭按钮,可添加图标及标题
**Version record:
**Version       Author         Data          Description
**v1.0.1        frieryumao   2019.07.24        first draft
*******************************************************************************/
#include <QDialog>
#include <QMouseEvent>
#include <QPoint>
#include <QCursor>
#include <QRect>
#include <QApplication>
#include <QDesktopWidget>
#include <QString>
#include <QWidget>
#include <QPushButton>
#include <QLabel>
#include<QBoxLayout>

namespace Ui {
class FramelessWidget;
}

class FramelessWidget : public QWidget
{
    Q_OBJECT

public:
    explicit FramelessWidget(QWidget *parent = 0);
    ~FramelessWidget();

    /******************************************************************************
    * Function:设置主窗口/标题栏背景色
    * InPut   :背景色
    * OutPut  :添加背景色
    * Return  :无
    * Other   :
    * Author  : frieryumao 2019.07.24
    *******************************************************************************/
    void SetBackgroundColor(QString bgcolor); // 设置背景颜色
    void SetTittleBackgroundColor(QString bgcolor);
    /******************************************************************************
    * Function:添加最小化/最大化/关闭按钮
    * InPut   :无
    * OutPut  :添加最小化/最大化/关闭按钮
    * Return  :无
    * Other   :
    * Author  : frieryumao 2019.07.24
    *******************************************************************************/
    void AddMinButton();
    void AddMaxButton();
    void AddcloseButton();
    /******************************************************************************
    * Function:从布局中删除最小化/最大化/关闭按钮
    * InPut   :无
    * OutPut  :从布局中删除最小化/最大化/关闭按钮
    * Return  :无
    * Other   :
    * Author  : frieryumao 2019.07.24
    *******************************************************************************/
    void DeleteMinButton();
    void DeleteMaxButton();
    void DeletecloseButton();
    /******************************************************************************
    * Function:删除标题栏布局,使得标题栏可编辑
    * InPut   :无
    * OutPut  :无
    * Return  :无
    * Other   :
    * Author  : frieryumao 2019.07.24
    *******************************************************************************/
    void EditTitleLayout();
    /******************************************************************************
    * Function:双击标题栏可最大化
    * InPut   :activateFlag = true 激活
    * OutPut  :双击标题栏可最大化
    * Return  :无
    * Other   :
    * Author  : frieryumao 2019.07.24
    *******************************************************************************/
    void ActivationDoubleClick(bool activateFlag = false);

protected:


    void mousePressEvent(QMouseEvent*event);
    void mouseMoveEvent(QMouseEvent*event);
    void mouseReleaseEvent(QMouseEvent*event);
    void resizeEvent(QResizeEvent *event);
    void mouseDoubleClickEvent(QMouseEvent *event);
    void keyPressEvent(QKeyEvent *event);

    /******************************************************************************
    * Function:添加标题栏布局
    * InPut   :无
    * OutPut  :添加标题栏布局
    * Return  :无
    * Other   :
    * Author  : frieryumao 2019.07.24
    *******************************************************************************/
    void SetTittleLayout();//标题栏布局

private slots:
    /******************************************************************************
    * Function:最小化/最大化/关闭按钮对应槽函数
    * InPut   :无
    * OutPut  :无
    * Return  :无
    * Other   :
    * Author  : frieryumao 2019.07.24
    *******************************************************************************/
    void onMin( bool );
    void onMax(bool);
    void onClose( bool );


public:
    QPushButton     *m_minOrNormalPushBtn; // 最小化按钮
    QPushButton     *m_maxPushBtn; // 最大化按钮
    QPushButton     *m_closePushBtn;// 关闭按钮

private:
    Ui::FramelessWidget *ui;
    QPoint          m_offset;//偏移量
     bool           m_mousePressed;
    int             m_border;
    QRect           m_availableWindRect;

    QHBoxLayout     *m_hlayout;//水平布局
    QVBoxLayout     *m_vlayout;//垂直布局
    QLabel          *m_tittleLabel;
    bool            m_acDoubleClick;


//    QLabel *m_tittleBgColor;//设置标题背景色
};

#endif // FRAMELESSWIDGET_H

#include "framelesswidget.h"
#include "ui_framelesswidget.h"
#include<QScreen>
#include <QDebug>

#define BTNSIZE 35


FramelessWidget::FramelessWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::FramelessWidget)
{
    ui->setupUi(this);

    this->setObjectName("FramelessWidget");
    this->setWindowFlags(Qt::Window|Qt::FramelessWindowHint
                         |Qt::WindowSystemMenuHint
                         |Qt::WindowMinimizeButtonHint
                         |Qt::WindowMaximizeButtonHint );
    this->setMouseTracking(true);
    setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
    m_border = 4;
    m_mousePressed = false;
    m_acDoubleClick = false;
    QDesktopWidget* desktop = QApplication::desktop();
    qDebug() << "Rect:" << desktop->availableGeometry();
    m_availableWindRect = QRect(desktop->availableGeometry());
    m_tittleLabel = new QLabel(this);
    m_tittleLabel->setGeometry(0,1,this->width(),BTNSIZE);
    m_tittleLabel->setObjectName("tittlebgLabel");
    m_tittleLabel->setStyleSheet("#tittlebgLabel{background-color:#54FF9F;}");

    this->AddMinButton();
    this->AddMaxButton();
    this->AddcloseButton();
    SetTittleLayout();
//    connect (m_minOrNormalPushBtn,SIGNAL(clicked(bool)),SLOT(onMin(bool)));
//    connect (m_maxPushBtn,SIGNAL(clicked(bool)),SLOT(onMax(bool)));
//    connect (m_closePushBtn,SIGNAL(clicked(bool)),SLOT(onClose(bool)));


}

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

void FramelessWidget::mouseReleaseEvent(QMouseEvent *event)
{

    if (event->button() == Qt::LeftButton)
    {
        m_mousePressed = false;
    }
    event->ignore();
    setCursor(Qt::ArrowCursor);
    QWidget::mouseReleaseEvent(event);
}

void FramelessWidget::mousePressEvent(QMouseEvent *event)
{
    setFocus();

    if (event->button() == Qt::LeftButton)
    {
        m_offset = event->pos();
        //鼠标在标题栏区域  QRect ( int left, int top, int width, int height )
        if(QRect(0,0,width()-120,BTNSIZE).contains(event->pos()))
        {
            m_mousePressed = true;
        }

    }

    QWidget::mousePressEvent(event);

}

void FramelessWidget::mouseMoveEvent(QMouseEvent *event)
{

    if (m_mousePressed)
    {
        //          //以下是防止窗口拖出可见范围外
        QRect widgetRect(this->geometry());
        QPoint point(event->globalPos() - m_offset);
        //左移
        int x1 =  this->width() - BTNSIZE;//窗口宽度 - BTNSIZE
        if (abs(point.x()) >= x1 && point.x()<=0)//
        {
            point = QPoint(-abs(x1),point.y());
        }
        //下移
        int y = m_availableWindRect.bottomRight().y() - BTNSIZE;
        if (point.y() >= y && widgetRect.topLeft().y() >= y)
        {
            point = QPoint(point.x(),y);
        }
        //上移
        if (point.y() <= 0)
        {
            point = QPoint(point.x(),0);
        }
        //右移
        int x = m_availableWindRect.bottomRight().x() - BTNSIZE;
        if (point.x() >= x && widgetRect.topLeft().x() >= x)
        {
            point = QPoint(x,point.y());
        }

        move(point);
    }

    QWidget::mouseMoveEvent(event);
}

void FramelessWidget::SetBackgroundColor(QString bgcolor)
{
    bgcolor="#FramelessWidget{background-color:"+bgcolor + ";}";
    this->setStyleSheet(bgcolor);
}

void FramelessWidget::SetTittleBackgroundColor(QString bgcolor)
{
    bgcolor="background-color:"+bgcolor + ";";
    m_tittleLabel->setStyleSheet(bgcolor);
}

void FramelessWidget::EditTitleLayout()
{
    while(m_vlayout->count())
    {
        QWidget *pWidget=m_vlayout->itemAt(0)->widget();
        if (pWidget)
        {
//            pWidget->setParent (NULL);

            m_vlayout->removeWidget(pWidget);
//            delete pWidget;
        }
        else
        {
            QLayout *pLayout=m_vlayout->itemAt(0)->layout();
            if (pLayout)
            {
                while(pLayout->count())
                {
                    QWidget *pTempWidget=pLayout->itemAt(0)->widget();
                    if (pTempWidget)
                    {
//                        pTempWidget->setParent (NULL);

                        pLayout->removeWidget(pTempWidget);
//                        delete pTempWidget;
                    }
                    else
                    {
                        pLayout->removeItem(pLayout->itemAt(0));
                    }
                }
            }

            m_vlayout->removeItem(m_vlayout->itemAt(0));
        }
    }
    delete m_vlayout;
}

void FramelessWidget::SetTittleLayout()
{
    m_hlayout = new QHBoxLayout();
    m_hlayout->addStretch();
    m_hlayout->addWidget(m_minOrNormalPushBtn);
     m_hlayout->addWidget(m_maxPushBtn);
    m_hlayout->addWidget(m_closePushBtn);
    m_hlayout->setMargin(0);
    m_vlayout = new QVBoxLayout(this);
    m_vlayout->addLayout(m_hlayout);
    m_vlayout->addStretch();
    m_vlayout->setMargin(0);
    setLayout(m_vlayout);
}

void FramelessWidget::DeleteMinButton()
{
    m_minOrNormalPushBtn->setParent(0);
}

void FramelessWidget::DeleteMaxButton()
{
    m_maxPushBtn->setParent(0);
}

void FramelessWidget::DeletecloseButton()
{
    m_closePushBtn->setParent(0);
}

void FramelessWidget::AddMinButton()
{
    m_minOrNormalPushBtn = new QPushButton(this);
//    m_minOrNormalPushBtn->resize(BTNSIZE,BTNSIZE);
//        m_minOrNormalPushBtn->setGeometry (this->width () - 3*BTNSIZE,0,BTNSIZE,BTNSIZE);
    m_minOrNormalPushBtn->setFlat(true);
    m_minOrNormalPushBtn->setFixedSize(BTNSIZE,BTNSIZE);
    m_minOrNormalPushBtn->setStyleSheet("QPushButton{border-style: none;}"
                                        "QPushButton:hover{background-color:lightgray; color: white;}"
                                        "QPushButton:pressed{background-color:rgb(85, 170, 255); border-style: inset; }");
    m_minOrNormalPushBtn->setCursor(Qt::PointingHandCursor);
    m_minOrNormalPushBtn->setIcon( QIcon(":/resource/mainimage/main_minimize.png")  );
    m_minOrNormalPushBtn->setToolTip(QObject::tr("Min"));
//    m_hlayout->addWidget(m_minOrNormalPushBtn);
    connect (m_minOrNormalPushBtn,SIGNAL(clicked(bool)),SLOT(onMin(bool)));

}

void FramelessWidget::AddcloseButton()
{
    m_closePushBtn = new QPushButton(this);
//    m_closePushBtn->resize(BTNSIZE,BTNSIZE);
//        m_closePushBtn->setGeometry (this->width () - BTNSIZE,0,BTNSIZE,BTNSIZE);
    m_closePushBtn->setFixedSize(BTNSIZE,BTNSIZE);
    m_closePushBtn->setFlat(true);
    m_closePushBtn->setStyleSheet("QPushButton{border-style: none/*;border-top-right-radius:5px*/}"
                                  "QPushButton:hover{background-color:red;color: white;}"
                                  "QPushButton:pressed{background-color:rgba(85, 170, 255,200); border-style: inset; }");
    m_closePushBtn->setCursor(Qt::PointingHandCursor);
    m_closePushBtn->setIcon(  QIcon(":/resource/mainimage/close.png")  );
    m_closePushBtn->setToolTip(QObject::tr("Quit"));
//    m_hlayout->addWidget(m_closePushBtn);
    connect (m_closePushBtn,SIGNAL(clicked(bool)),SLOT(onClose(bool)));

}

void FramelessWidget::AddMaxButton()
{
    m_maxPushBtn = new QPushButton(this);
//    m_maxPushBtn->resize(BTNSIZE,BTNSIZE);
//    m_maxPushBtn->setGeometry (this->width () - 2*BTNSIZE,0,BTNSIZE,BTNSIZE);
    m_maxPushBtn->setFixedSize(BTNSIZE,BTNSIZE);
    m_maxPushBtn->setFlat (true);
    m_maxPushBtn->setStyleSheet("QPushButton{border-style: none;}"
                                "QPushButton:hover{background-color:lightgray; color: white;}"
                                "QPushButton:pressed{background-color:rgb(85, 170, 255); border-style: inset; }");
    m_maxPushBtn->setCursor(Qt::PointingHandCursor);
    m_maxPushBtn->setIcon( QIcon(":/resource/mainimage/main_maximize.png") );
    m_maxPushBtn->setToolTip(QObject::tr("Max"));
//    m_hlayout->addWidget(m_maxPushBtn);
    connect (m_maxPushBtn,SIGNAL(clicked(bool)),SLOT(onMax(bool)));

}

void FramelessWidget::onMin(bool)
{
    if( windowState() != Qt::WindowMinimized )
    {
        setWindowState( Qt::WindowMinimized );
    }
}

void FramelessWidget::onMax(bool)
{
    if( windowState() != Qt::WindowMaximized )
    {
        setWindowState( Qt::WindowMaximized );
    }
    else
    {
        setWindowState( Qt::WindowNoState );
//        QRect deskRect = QApplication::desktop()->availableGeometry();
//        this->move((deskRect.width() - this->width()) / 2, (deskRect.height() - this->height()) / 2);
    }

}

void FramelessWidget::onClose(bool)
{
    emit close();
}


void FramelessWidget::mouseDoubleClickEvent(QMouseEvent *event)
{
    if( m_acDoubleClick && event->y() < BTNSIZE && event->x() < this->width() )
    {
        onMax(true);
        event->accept();
    }
    else
    {
        event->ignore();
    }
    QWidget::mouseDoubleClickEvent(event);
}

void FramelessWidget::ActivationDoubleClick(bool activateFlag)
{
    m_acDoubleClick = activateFlag;
}

void FramelessWidget::keyPressEvent(QKeyEvent *event)
{
    if(event->key() == Qt::Key_Escape)
    {
        emit close();
        event->accept();
    }
    QWidget::keyPressEvent(event);
}

void FramelessWidget::resizeEvent(QResizeEvent *event)
{
    Q_UNUSED(event)
    m_tittleLabel->setGeometry(0,1,this->width(),BTNSIZE);
//    m_tittleLabel->resize(this->size().width(),BTNSIZE);
    QWidget::resizeEvent(event);

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值