无边框窗口拖拽标题栏可移动,且限制窗口可移出屏幕的范围,布局最大化、最小化、关闭按钮,双击标题栏最大化,设置标题栏颜色,窗口背景颜色等功能。
使用方法:
其中类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);
}