2022-07-30 11:50:01 +08:00

414 lines
11 KiB
C++

#include "BaseWgt.h"
#include <QHoverEvent>
#include <QApplication>
#include <QDesktopWidget>
#include <QDebug>
#include <QDir>
enum MouseStyle{ NORMAL, RIGHT, BOTTOMRIGHT, BOTTOM } mouseStyle;
BaseWgt::BaseWgt(QWidget *parent)
: QWidget(parent)
, m_bResizable(true)
, m_iMarginWidth(6)
, m_bPressed(false)
, m_ptPressPos(0, 0)
, m_bIsMaxState(false)
{
//this->setAttribute(Qt::WA_TranslucentBackground);
this->setWindowFlags(Qt::FramelessWindowHint | Qt::Window);
this->initUiControl();
this->initSignalSlotConn();
this->setAttribute(Qt::WA_Hover);
this->installEventFilter(this);
}
BaseWgt::~BaseWgt()
{
}
bool BaseWgt::eventFilter(QObject *obj, QEvent *event)
{
if (obj != this && obj != m_pTopWgt)
{
return false;
}
switch(event->type())
{
case QEvent::MouseMove:
{
QMouseEvent *mouseEvent = dynamic_cast<QMouseEvent *>(event);
if (m_bPressed && mouseStyle == NORMAL && NULL != mouseEvent)
{
//如果是最大化,则先恢复正常状态
if (m_bIsMaxState)
{
QPoint pt = this->mapFromGlobal(QCursor::pos());
int iMaxWidth = this->width();
m_bIsMaxState = !m_bIsMaxState;
this->resize(m_normalRect.size());
m_pMaxBtn->setProperty("maxState", false);
m_pMaxBtn->setToolTip("最大化");
QStyle *pStyle = this->style();
pStyle->unpolish(m_pMaxBtn);
pStyle->polish(m_pMaxBtn);
m_ptPressPos.setY(pt.y());
m_ptPressPos.setX(pt.x() * (this->width() - 100) / (iMaxWidth - 100));
}
this->move(this->mapToGlobal(mouseEvent->pos()) - m_ptPressPos);
return true;
}
break;
}
//[1]鼠标在界面上移动
case QEvent::HoverMove:
{
QHoverEvent *hoverEvent = dynamic_cast<QHoverEvent *>(event);
if (m_bPressed)
{
//只能在界面右边或者右下角缩放界面
QPoint ptGlobalPos = this->mapToGlobal(hoverEvent->pos());
QPoint ptTopLeft = this->frameGeometry().topLeft();
QPoint ptBottomRight = this->frameGeometry().bottomRight();
switch(mouseStyle)
{
case BOTTOM:
if (ptGlobalPos.y() - ptTopLeft.y() > this->minimumHeight())
{
ptBottomRight.setY(ptGlobalPos.y());
}
else
{
ptBottomRight.setY(ptTopLeft.y() + this->minimumHeight());
}
break;
case RIGHT:
if (ptGlobalPos.x() - ptTopLeft.x() > this->minimumWidth())
{
ptBottomRight.setX(ptGlobalPos.x());
}
else
{
ptBottomRight.setX(ptTopLeft.x() + this->minimumWidth());
}
break;
case BOTTOMRIGHT:
if (ptGlobalPos.y() - ptTopLeft.y() > this->minimumHeight())
{
ptBottomRight.setY(ptGlobalPos.y());
}
else
{
ptBottomRight.setY(ptTopLeft.y() + this->minimumHeight());
}
if (ptGlobalPos.x() - ptTopLeft.x() > this->minimumWidth())
{
ptBottomRight.setX(ptGlobalPos.x());
}
else
{
ptBottomRight.setX(ptTopLeft.x() + this->minimumWidth());
}
break;
}
this->setGeometry(QRect(ptTopLeft, ptBottomRight));
return true;
}
else
{
changeMouseStyle(hoverEvent->pos());
}
}
break;
//[1]end 鼠标在界面上移动
//[2]鼠标按下
case QEvent::MouseButtonPress:
{
//在顶部/右方边缘/右下角时,鼠标按下时做标记
QMouseEvent *mouseEvent = dynamic_cast<QMouseEvent *>(event);
if (mouseEvent->button() == Qt::LeftButton)
{
if (mouseEvent->pos().y() <= TOP_HEIGHT | mouseStyle != NORMAL)
{
qDebug()<<"pressed in";
m_bPressed = true;
m_ptPressPos = mouseEvent->globalPos() - this->frameGeometry().topLeft();
}
}
}
break;
//[2]end 鼠标按下
//[3]鼠标左键松开
case QEvent::MouseButtonRelease:
{
QMouseEvent *mouseEvent = dynamic_cast<QMouseEvent *>(event);
if (mouseEvent->button() == Qt::LeftButton)
{
qDebug()<<"release in";
m_bPressed = false;
changeMouseStyle(mouseEvent->pos());
}
}
break;
//[3]end 鼠标左键松开
//[4]鼠标双击
case QEvent::MouseButtonDblClick:
{
QMouseEvent *mouseEvent = dynamic_cast<QMouseEvent *>(event);
if (mouseEvent->button() == Qt::LeftButton && mouseEvent->pos().y() <= TOP_HEIGHT)
{
qDebug()<<"dbc in";
maximumBtnClickedSlot();
return true;
}
}
break;
//[4]鼠标双击
case QEvent::Show:
{
repaint();
}
default:
break;
}
return false;
}
void BaseWgt::changeMouseStyle(const QPoint &ptMousePos)
{
if (!m_bResizable)
{
setCursor(Qt::ArrowCursor);//正常样式
mouseStyle = NORMAL;
return;
}
if (m_bIsMaxState)
{
setCursor(Qt::ArrowCursor);//正常样式
mouseStyle = NORMAL;
return;
}
int iPosX = ptMousePos.x();
int iPosY = ptMousePos.y();
int iWidth = this->width();
int iHeight = this->height();
if (iPosX >= iWidth - m_iMarginWidth && iPosX <= iWidth)
{
if (iPosY >= iHeight - m_iMarginWidth && iPosY <= iHeight)
{
setCursor(Qt::SizeFDiagCursor);//右下
mouseStyle = BOTTOMRIGHT;
return;
}
setCursor(Qt::SizeHorCursor);
mouseStyle = RIGHT;//右
return;
}
if (iPosY >= iHeight - m_iMarginWidth && iPosY <= iHeight)
{
setCursor(Qt::SizeVerCursor);//下
mouseStyle = BOTTOM;
return;
}
setCursor(Qt::ArrowCursor);
mouseStyle = NORMAL;
return;
}
//[4]设置是否可以伸缩
void BaseWgt::setResizable(bool bResizable)
{
m_bResizable = bResizable;
}
//[4]end 设置是否可以伸缩
//[5]设置鼠标样式在界面边缘改变的范围
void BaseWgt::setMargin(const int &iMargin)
{
m_iMarginWidth = iMargin;
}
//[5]end 设置鼠标样式在界面边缘改变的范围
void BaseWgt::initUiControl()
{
//设置使程序支持中文字符
QTextCodec *codec = QTextCodec::codecForName("System"); // 获取系统编码
QTextCodec::setCodecForLocale(codec);
// QTextCodec::setCodecForCStrings(codec);
// QTextCodec::setCodecForTr(codec);
QDesktopWidget*pDeskTop = QApplication::desktop();
if(pDeskTop->screenCount() >= 2)
{
m_screenRect = pDeskTop->screenGeometry(pDeskTop->primaryScreen() == 0?1:0);
}
else
{
m_screenRect = pDeskTop->availableGeometry();//保存屏幕大小
}
m_pBottomWgt = new QWidget(this);
m_pBottomWgt->setObjectName("m_pBottomWgt");
QVBoxLayout *pVBoxLayoutBottom = new QVBoxLayout(this);
pVBoxLayoutBottom->setMargin(0);
pVBoxLayoutBottom->setSpacing(0);
pVBoxLayoutBottom->addWidget(m_pBottomWgt);
m_pTopWgt = new QWidget(this);
m_pTopWgt->installEventFilter(this);
m_pTopWgt->setObjectName("m_pTopWgt");
m_pTopWgt->setMinimumHeight(TOP_HEIGHT);
m_pTopWgt->setMaximumHeight(TOP_HEIGHT);
//m_pTopWgt->setAttribute(Qt::WA_Hover);
m_pMainWgt = new QWidget(this);
m_pMainWgt->setObjectName("m_pMainWgt");
QVBoxLayout *pVBoxLayout = new QVBoxLayout(m_pBottomWgt);
pVBoxLayout->setMargin(0);
pVBoxLayout->setSpacing(0);
pVBoxLayout->addWidget(m_pTopWgt);
pVBoxLayout->addWidget(m_pMainWgt);
m_pIconLabel = new QLabel(this);
m_pTitleLbl = new QLabel(this);
m_pMinBtn = new QPushButton(this);
m_pMaxBtn = new QPushButton(this);
m_pCloseBtn = new QPushButton(this);
m_pIconLabel->setMinimumSize(20, 20);
m_pIconLabel->setMaximumSize(20, 20);
m_pMinBtn->setMinimumSize(27, 22);
m_pMinBtn->setMaximumSize(27, 22);
m_pMaxBtn->setMinimumSize(27, 22);
m_pMaxBtn->setMaximumSize(27, 22);
m_pCloseBtn->setMinimumSize(42, 22);
m_pCloseBtn->setMaximumSize(42, 22);
m_pMinBtn->setToolTip("最小化");
m_pMaxBtn->setToolTip("最大化");
m_pCloseBtn->setToolTip("关闭");
m_pIconLabel->setObjectName("m_pIconLabel");
m_pTitleLbl->setObjectName("m_pTitleLbl");
m_pMinBtn->setObjectName("m_pMinBtn");
m_pMaxBtn->setObjectName("m_pMaxBtn");
m_pCloseBtn->setObjectName("m_pCloseBtn");
QHBoxLayout *pHBoxLayout = new QHBoxLayout;
pHBoxLayout->setContentsMargins(8, 2, 2, 2);
pHBoxLayout->setSpacing(1);
pHBoxLayout->addWidget(m_pIconLabel);
pHBoxLayout->addSpacing(5);
pHBoxLayout->addWidget(m_pTitleLbl);
pHBoxLayout->addStretch();
pHBoxLayout->addWidget(m_pMinBtn);
pHBoxLayout->addWidget(m_pMaxBtn);
pHBoxLayout->addWidget(m_pCloseBtn);
m_pTopWgt->setLayout(pHBoxLayout);
//载入样式表
QFile file(WGT_STYLE_PATH);
if (file.open(QIODevice::ReadOnly))
{
QString strSheet = file.readAll();
setStyleSheet(strSheet);
}
}
//初始化信号槽连接
void BaseWgt::initSignalSlotConn()
{
connect(m_pMinBtn, SIGNAL(clicked()), this, SLOT(minimumBtnClickedSlot()));
connect(m_pMaxBtn, SIGNAL(clicked()), this, SLOT(maximumBtnClickedSlot()));
connect(m_pCloseBtn, SIGNAL(clicked()), this, SLOT(close()));
}
//最小化按钮单击槽函数
void BaseWgt::minimumBtnClickedSlot()
{
showMinimized();
}
//最大化按钮单击槽函数
void BaseWgt::maximumBtnClickedSlot()
{
m_bIsMaxState = !m_bIsMaxState;
if (m_bIsMaxState)
{
//记录下正常窗口的状态
m_normalRect.setTopLeft(this->frameGeometry().topLeft());
m_normalRect.setSize(this->size());
this->setGeometry(m_screenRect);
m_pMaxBtn->setProperty("maxState", true);
m_pMaxBtn->setToolTip("restore");
}
else
{
this->setGeometry(m_normalRect);
m_pMaxBtn->setProperty("maxState", false);
m_pMaxBtn->setToolTip("最大化");
}
QStyle *pStyle = this->style();
pStyle->unpolish(m_pMaxBtn);
pStyle->polish(m_pMaxBtn);
}
void BaseWgt::setSysIcon(const QString &url)
{
qDebug()<<QDir::currentPath();
QPixmap *pixmap = new QPixmap(url);
m_pTitleLbl->setPixmap(*pixmap);
}
//设置窗口标题
void BaseWgt::setWindowTitle(const QString &strTitle)
{
m_pTitleLbl->setText(strTitle);
m_pTitleLbl->setFixedSize(m_pTitleLbl->sizeHint());
m_pTitleLbl->setFixedHeight(22);
}
void BaseWgt::hideTopWgt()
{
m_pTopWgt->hide();
}
void BaseWgt::setTopWgtHiddent(bool bHide)
{
if(bHide)
{
m_pTopWgt->hide();
}
else
{
m_pTopWgt->show();
}
}
void BaseWgt::setCloseBtnVisible(bool bVisible)
{
if(!m_pCloseBtn) return;
m_pCloseBtn->setVisible(bVisible);
}