重构无边框窗体,鼠标拖动窗口改变大小功能,使得更加流畅不再依赖windows api
This commit is contained in:
parent
414fa36433
commit
db02113c2a
@ -97,34 +97,34 @@ QPushButton#btn_min,QPushButton#btn_max,QPushButton#btn_close{
|
||||
font: bold 12px;
|
||||
}
|
||||
QPushButton#btn_min{
|
||||
image:url(":/res/img/btn/btn_min.png");
|
||||
border:none;
|
||||
width:25px;
|
||||
height:25px;
|
||||
image:url(":/res/img/btn/btn_min.png");
|
||||
border:none;
|
||||
width:20px;
|
||||
height:20px;
|
||||
}
|
||||
QPushButton#btn_max{
|
||||
image:url(":/res/img/btn/btn_max.png");
|
||||
border:none;
|
||||
width:25px;
|
||||
height:25px;
|
||||
image:url(":/res/img/btn/btn_max.png");
|
||||
border:none;
|
||||
width:20px;
|
||||
height:20px;
|
||||
}
|
||||
QPushButton#btn_max[maximizeProperty='maximize'] {
|
||||
image:url(":/res/img/btn/btn_max.png");
|
||||
border:none;
|
||||
width:25px;
|
||||
height:25px;
|
||||
width:20px;
|
||||
height:20px;
|
||||
}
|
||||
QPushButton#btn_max[maximizeProperty='restore'] {
|
||||
image:url(":/res/img/btn/btn_max_restore.png");
|
||||
border:none;
|
||||
width:25px;
|
||||
height:25px;
|
||||
width:20px;
|
||||
height:20px;
|
||||
}
|
||||
QPushButton#btn_close{
|
||||
image:url(":/res/img/btn/btn_close.png");
|
||||
border:none;
|
||||
width:25px;
|
||||
height:25px;
|
||||
image:url(":/res/img/btn/btn_close.png");
|
||||
border:none;
|
||||
width:20px;
|
||||
height:20px;
|
||||
}
|
||||
|
||||
QPushButton#btn_min:hover,QPushButton#btn_max:hover,QPushButton#btn_close:hover{
|
||||
|
@ -73,32 +73,32 @@ QPushButton#btn_min,QPushButton#btn_max,QPushButton#btn_close{
|
||||
QPushButton#btn_min{
|
||||
image:url(":/res/img/btn/btn_min.png");
|
||||
border:none;
|
||||
width:25px;
|
||||
height:25px;
|
||||
width:20px;
|
||||
height:20px;
|
||||
}
|
||||
QPushButton#btn_max{
|
||||
image:url(":/res/img/btn/btn_max.png");
|
||||
border:none;
|
||||
width:25px;
|
||||
height:25px;
|
||||
width:20px;
|
||||
height:20px;
|
||||
}
|
||||
QPushButton#btn_max[maximizeProperty='maximize'] {
|
||||
image:url(":/res/img/btn/btn_max.png");
|
||||
border:none;
|
||||
width:25px;
|
||||
height:25px;
|
||||
width:20px;
|
||||
height:20px;
|
||||
}
|
||||
QPushButton#btn_max[maximizeProperty='restore'] {
|
||||
image:url(":/res/img/btn/btn_max_restore.png");
|
||||
border:none;
|
||||
width:25px;
|
||||
height:25px;
|
||||
width:20px;
|
||||
height:20px;
|
||||
}
|
||||
QPushButton#btn_close{
|
||||
image:url(":/res/img/btn/btn_close.png");
|
||||
border:none;
|
||||
width:25px;
|
||||
height:25px;
|
||||
image:url(":/res/img/btn/btn_close.png");
|
||||
border:none;
|
||||
width:20px;
|
||||
height:20px;
|
||||
}
|
||||
|
||||
QPushButton#btn_min:hover,QPushButton#btn_max:hover,QPushButton#btn_close:hover{
|
||||
|
287
src/sui.cpp
287
src/sui.cpp
@ -2,11 +2,11 @@
|
||||
sui::sui(QWidget *parent)
|
||||
: QWidget(parent),
|
||||
m_layout(new QVBoxLayout),
|
||||
m_widget(new QWidget),
|
||||
m_widget(new QWidget),
|
||||
m_press(false),
|
||||
m_border_width(5)
|
||||
{
|
||||
m_title=new sui_title(this);
|
||||
m_title = new sui_title(this);
|
||||
setObjectName(tr("m_widget"));
|
||||
m_layout->addWidget(m_title);
|
||||
m_title->setMouseTracking(true);
|
||||
@ -22,7 +22,6 @@ sui::sui(QWidget *parent)
|
||||
}
|
||||
sui::~sui()
|
||||
{
|
||||
|
||||
}
|
||||
void sui::showEvent(QShowEvent *event)
|
||||
{
|
||||
@ -41,78 +40,242 @@ void sui::paintEvent(QPaintEvent *event)
|
||||
QWidget::paintEvent(event);
|
||||
}
|
||||
|
||||
void sui::region(const QPoint ¤tGlobalPoint)
|
||||
{
|
||||
// 获取窗体在屏幕上的位置区域,topLeft为坐上角点,rightButton为右下角点
|
||||
QRect rect = this->rect();
|
||||
|
||||
// 将左上角的(0,0)转化为全局坐标
|
||||
QPoint topLeft = this->mapToGlobal(rect.topLeft());
|
||||
QPoint rightButton = this->mapToGlobal(rect.bottomRight());
|
||||
|
||||
// 当前鼠标的坐标
|
||||
int x = currentGlobalPoint.x();
|
||||
int y = currentGlobalPoint.y();
|
||||
|
||||
if (((topLeft.x() + m_border_width >= x) && (topLeft.x() <= x)) && ((topLeft.y() + m_border_width >= y) && (topLeft.y() <= y)))
|
||||
{
|
||||
// 左上角
|
||||
ori = LEFTTOP;
|
||||
// 设置光标形状
|
||||
this->setCursor(QCursor(Qt::SizeFDiagCursor));
|
||||
}
|
||||
else if (((x >= rightButton.x() - m_border_width) && (x <= rightButton.x())) && ((y >= rightButton.y() - m_border_width) && (y <= rightButton.y())))
|
||||
{
|
||||
// 右下角
|
||||
ori = RIGHTBOTTOM;
|
||||
this->setCursor(QCursor(Qt::SizeFDiagCursor));
|
||||
}
|
||||
else if (((x <= topLeft.x() + m_border_width) && (x >= topLeft.x())) && ((y >= rightButton.y() - m_border_width) && (y <= rightButton.y())))
|
||||
{
|
||||
// 左下角
|
||||
ori = LEFTBOTTOM;
|
||||
this->setCursor(QCursor(Qt::SizeBDiagCursor));
|
||||
}
|
||||
else if (((x <= rightButton.x()) && (x >= rightButton.x() - m_border_width)) && ((y >= topLeft.y()) && (y <= topLeft.y() + m_border_width)))
|
||||
{
|
||||
// 右上角
|
||||
ori = RIGHTTOP;
|
||||
this->setCursor(QCursor(Qt::SizeBDiagCursor));
|
||||
}
|
||||
else if ((x <= topLeft.x() + m_border_width) && (x >= topLeft.x()))
|
||||
{
|
||||
// 左边
|
||||
ori = LEFT;
|
||||
this->setCursor(QCursor(Qt::SizeHorCursor));
|
||||
}
|
||||
else if ((x <= rightButton.x()) && (x >= rightButton.x() - m_border_width))
|
||||
{
|
||||
// 右边
|
||||
ori = RIGHT;
|
||||
this->setCursor(QCursor(Qt::SizeHorCursor));
|
||||
}
|
||||
else if ((y >= topLeft.y()) && (y <= topLeft.y() + m_border_width))
|
||||
{
|
||||
// 上边
|
||||
ori = UP;
|
||||
this->setCursor(QCursor(Qt::SizeVerCursor));
|
||||
}
|
||||
else if ((y <= rightButton.y()) && (y >= rightButton.y() - m_border_width))
|
||||
{
|
||||
// 下边
|
||||
ori = DOWN;
|
||||
this->setCursor(QCursor(Qt::SizeVerCursor));
|
||||
}
|
||||
else
|
||||
{
|
||||
// 默认
|
||||
ori = NONE;
|
||||
this->setCursor(QCursor(Qt::ArrowCursor));
|
||||
}
|
||||
}
|
||||
|
||||
void sui::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
if ((event->button() == Qt::LeftButton))
|
||||
switch (event->button())
|
||||
{
|
||||
case Qt::LeftButton:
|
||||
m_press = true;
|
||||
m_point = (event->globalPosition() - this->pos()).toPoint();
|
||||
event->accept();
|
||||
|
||||
if (ori != NONE)
|
||||
{
|
||||
// 返回当前抓取鼠标输入的窗口
|
||||
this->mouseGrabber();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_point = event->globalPosition().toPoint() - this->frameGeometry().topLeft();
|
||||
// globalPos()鼠标位置,topLeft()窗口左上角的位置
|
||||
}
|
||||
break;
|
||||
case Qt::RightButton:
|
||||
this->setWindowState(Qt::WindowMinimized);
|
||||
break;
|
||||
default:
|
||||
QWidget::mousePressEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
void sui::mouseMoveEvent(QMouseEvent *event)
|
||||
{
|
||||
if (m_press)
|
||||
|
||||
QPoint globalPoint = event->globalPosition().toPoint();
|
||||
|
||||
QRect rect = this->rect();
|
||||
QPoint topLeft = mapToGlobal(rect.topLeft());
|
||||
QPoint bottomRight = mapToGlobal(rect.bottomRight());
|
||||
|
||||
if (this->windowState() != Qt::WindowMaximized)
|
||||
{
|
||||
move(event->globalPosition().toPoint() - m_point);
|
||||
event->accept();
|
||||
// 没有按下左键时
|
||||
if (!m_press)
|
||||
{
|
||||
// 窗口大小的改变——判断鼠标位置,改变光标形状
|
||||
this->region(globalPoint);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ori != NONE)
|
||||
{
|
||||
QRect newRect(topLeft, bottomRight);
|
||||
|
||||
switch (ori)
|
||||
{
|
||||
case LEFT:
|
||||
|
||||
if (bottomRight.x() - globalPoint.x() <= this->minimumWidth())
|
||||
{
|
||||
// 小于界面的最小宽度时,设置为左上角横坐标为窗口x
|
||||
newRect.setLeft(topLeft.x());
|
||||
// 只改变左边界
|
||||
}
|
||||
else
|
||||
{
|
||||
newRect.setLeft(globalPoint.x());
|
||||
}
|
||||
break;
|
||||
case RIGHT:
|
||||
// 只能改变右边界
|
||||
newRect.setWidth(globalPoint.x() - topLeft.x());
|
||||
break;
|
||||
case UP:
|
||||
if (bottomRight.y() - globalPoint.y() <= this->minimumHeight())
|
||||
{
|
||||
newRect.setY(topLeft.y());
|
||||
}
|
||||
else
|
||||
{
|
||||
newRect.setY(globalPoint.y());
|
||||
}
|
||||
break;
|
||||
case DOWN:
|
||||
newRect.setHeight(globalPoint.y() - topLeft.y());
|
||||
break;
|
||||
case LEFTTOP:
|
||||
if (bottomRight.x() - globalPoint.x() <= this->minimumWidth())
|
||||
{
|
||||
newRect.setX(topLeft.x());
|
||||
}
|
||||
else
|
||||
{
|
||||
newRect.setX(globalPoint.x());
|
||||
}
|
||||
|
||||
if (bottomRight.y() - globalPoint.y() <= this->minimumHeight())
|
||||
{
|
||||
newRect.setY(topLeft.y());
|
||||
}
|
||||
else
|
||||
{
|
||||
newRect.setY(globalPoint.y());
|
||||
}
|
||||
break;
|
||||
case RIGHTTOP:
|
||||
if (globalPoint.x() - topLeft.x() >= this->minimumWidth())
|
||||
{
|
||||
newRect.setWidth(globalPoint.x() - topLeft.x());
|
||||
}
|
||||
else
|
||||
{
|
||||
newRect.setWidth(bottomRight.x() - topLeft.x());
|
||||
}
|
||||
if (bottomRight.y() - globalPoint.y() >= this->minimumHeight())
|
||||
{
|
||||
newRect.setY(globalPoint.y());
|
||||
}
|
||||
else
|
||||
{
|
||||
newRect.setY(topLeft.y());
|
||||
}
|
||||
break;
|
||||
case LEFTBOTTOM:
|
||||
if (bottomRight.x() - globalPoint.x() >= this->minimumWidth())
|
||||
{
|
||||
newRect.setX(globalPoint.x());
|
||||
}
|
||||
else
|
||||
{
|
||||
newRect.setX(topLeft.x());
|
||||
}
|
||||
if (globalPoint.y() - topLeft.y() >= this->minimumHeight())
|
||||
{
|
||||
newRect.setHeight(globalPoint.y() - topLeft.y());
|
||||
}
|
||||
else
|
||||
{
|
||||
newRect.setHeight(bottomRight.y() - topLeft.y());
|
||||
}
|
||||
break;
|
||||
case RIGHTBOTTOM:
|
||||
newRect.setWidth(globalPoint.x() - topLeft.x());
|
||||
newRect.setHeight(globalPoint.y() - topLeft.y());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
this->setGeometry(newRect);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 移动窗口
|
||||
move(event->globalPosition().toPoint() - m_point);
|
||||
event->accept();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 鼠标释放事件
|
||||
void sui::mouseReleaseEvent(QMouseEvent *event)
|
||||
{
|
||||
Q_UNUSED(event)
|
||||
m_press = false;
|
||||
}
|
||||
|
||||
bool sui::nativeEvent(const QByteArray &eventType, void *message, qintptr *result)
|
||||
{
|
||||
//Q_UNUSED(eventType)
|
||||
|
||||
MSG *param = static_cast<MSG *>(message);
|
||||
|
||||
switch (param->message)
|
||||
if (event->button() == Qt::LeftButton)
|
||||
{
|
||||
case WM_NCHITTEST:
|
||||
{
|
||||
int nX = GET_X_LPARAM(param->lParam) - this->geometry().x();
|
||||
int nY = GET_Y_LPARAM(param->lParam) - this->geometry().y();
|
||||
|
||||
// 如果鼠标位于子控件上,则不进行处理
|
||||
if (childAt(nX, nY) != nullptr)
|
||||
return QWidget::nativeEvent(eventType, message, result);
|
||||
|
||||
*result = HTCAPTION;
|
||||
|
||||
// 鼠标区域位于窗体边框,进行缩放
|
||||
if ((nX > 0) && (nX < m_border_width))
|
||||
*result = HTLEFT;
|
||||
|
||||
if ((nX > this->width() - m_border_width) && (nX < this->width()))
|
||||
*result = HTRIGHT;
|
||||
|
||||
if ((nY > 0) && (nY < m_border_width))
|
||||
*result = HTTOP;
|
||||
|
||||
if ((nY > this->height() - m_border_width) && (nY < this->height()))
|
||||
*result = HTBOTTOM;
|
||||
|
||||
if ((nX > 0) && (nX < m_border_width) && (nY > 0) && (nY < m_border_width))
|
||||
*result = HTTOPLEFT;
|
||||
|
||||
if ((nX > this->width() - m_border_width) && (nX < this->width()) && (nY > 0) && (nY < m_border_width))
|
||||
*result = HTTOPRIGHT;
|
||||
|
||||
if ((nX > 0) && (nX < m_border_width) && (nY > this->height() - m_border_width) && (nY < this->height()))
|
||||
*result = HTBOTTOMLEFT;
|
||||
|
||||
if ((nX > this->width() - m_border_width) && (nX < this->width()) && (nY > this->height() - m_border_width) && (nY < this->height()))
|
||||
*result = HTBOTTOMRIGHT;
|
||||
|
||||
return true;
|
||||
m_press = false;
|
||||
if (ori != NONE)
|
||||
{
|
||||
// 释放鼠标抓取
|
||||
this->releaseMouse();
|
||||
this->setCursor(QCursor(Qt::ArrowCursor));
|
||||
ori = NONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return QWidget::nativeEvent(eventType, message, result);
|
||||
}
|
||||
}
|
25
src/sui.h
25
src/sui.h
@ -2,13 +2,20 @@
|
||||
#define SUI_H
|
||||
|
||||
#include "common.h"
|
||||
#include <QMainWindow>
|
||||
#ifdef Q_OS_WIN
|
||||
#include <QWindow>
|
||||
#include <windowsx.h>
|
||||
#pragma execution_character_set("utf-8")
|
||||
#endif
|
||||
#include "sui_title.h"
|
||||
|
||||
typedef enum {
|
||||
UP=0,
|
||||
DOWN=1,
|
||||
LEFT,
|
||||
RIGHT,
|
||||
LEFTTOP,
|
||||
LEFTBOTTOM,
|
||||
RIGHTBOTTOM,
|
||||
RIGHTTOP,
|
||||
NONE
|
||||
}Orient;
|
||||
|
||||
class sui : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
@ -16,19 +23,21 @@ public:
|
||||
explicit sui(QWidget *parent = 0);
|
||||
~sui();
|
||||
sui_title* title() { return m_title; }
|
||||
void region(const QPoint ¤tGlobalPoint); //鼠标的位置,改变光标
|
||||
private:
|
||||
QVBoxLayout *m_layout;
|
||||
QWidget *m_widget;
|
||||
QPoint m_point;
|
||||
bool m_press;
|
||||
int m_border_width;
|
||||
sui_title *m_title;
|
||||
Orient ori;
|
||||
|
||||
sui_title *m_title;
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *event);
|
||||
void showEvent(QShowEvent *event);
|
||||
void mouseMoveEvent(QMouseEvent *event);
|
||||
void mousePressEvent(QMouseEvent *event);
|
||||
void mouseReleaseEvent(QMouseEvent *event);
|
||||
bool nativeEvent(const QByteArray &eventType, void *message, qintptr *result);
|
||||
};
|
||||
#endif // SUI_H
|
Loading…
Reference in New Issue
Block a user