QT无边框
// 在widget构造中添加如下即可实现无边框
setWindowFlags(Qt::FramelessWindowHint); //设置无边框
可拖动
当实现无边框之后,你会发现无法拖动了。
或许我们需要了解下窗口是怎么被拖动的
- 通过标题栏拖动窗口
move
窗口位置
因此有两种方案可以解决无法拖动
// 1. 通过定位到标题栏拖动窗口
// 重写nativeEvent事件,是QT用于处理原生系统事件
bool Widget::nativeEvent(const QByteArray& eventType, void* message, long* result)
{
MSG* msg = (MSG*)message;
switch (msg->message)
{
case WM_NCHITTEST:
int xPos = GET_X_LPARAM(msg->lParam) - this->frameGeometry().x();
int yPos = GET_Y_LPARAM(msg->lParam) - this->frameGeometry().y();
if (xPos && xPos < width() && yPos && yPos < height())
*result = HTCAPTION;
else
return false;
return true;
}
return false;
}
PS:
GET_X_LPARAM(msg->lParam)
获取鼠标在屏幕中坐标,原点为屏幕左上角
this->frameGeometry().x()
获取窗口左上角x坐标
通过计算,可将鼠标坐标系换算成窗口坐标系中
HTCAPTION
是一个常量,表示鼠标在窗口的标题栏上
此种处理有缺陷,会导致无法点击窗口中控件
// 2. move窗口位置
// 通过重写mousePressEvent、mouseMoveEvent事件
protected:
void mousePressEvent(QMouseEvent* event);
void mouseMoveEvent(QMouseEvent* event);
private:
QPoint m_dragPosition; // 用于窗口移动的临时变量
void Widget::mousePressEvent(QMouseEvent* event)
{
// 当鼠标左键按下时记录鼠标的全局坐标与窗口左上角的坐标差
if (event->button() == Qt::LeftButton) {
m_dragPosition = event->pos();
event->accept();
}
}
void Widget::mouseMoveEvent(QMouseEvent* event)
{
// 当鼠标左键被按下时移动窗口
if (event->buttons() & Qt::LeftButton) {
move(event->globalPos() - m_dragPosition);
event->accept();
}
}
PS:
pos()
获取鼠标在窗口坐标系中位置
globalPos()
获取鼠标在屏幕坐标系中位置
原理:
通过鼠标移动中,计算窗口左上角位置,实现移动
可调整大小
同上,重写nativeEvent即可
bool Widget::nativeEvent(const QByteArray& eventType, void* message, long* result)
{
MSG* msg = (MSG*)message;
switch (msg->message)
{
case WM_NCHITTEST:
int xPos = GET_X_LPARAM(msg->lParam) - this->frameGeometry().x();
int yPos = GET_Y_LPARAM(msg->lParam) - this->frameGeometry().y();
if (xPos && xPos < width() && yPos && yPos < height())
*result = HTCAPTION;
else if (xPos < boundaryWidth && yPos < boundaryWidth) //左上角
*result = HTTOPLEFT;
else if (xPos >= width() - boundaryWidth && yPos < boundaryWidth) //右上角
*result = HTTOPRIGHT;
else if (xPos < boundaryWidth && yPos >= height() - boundaryWidth) //左下角
*result = HTBOTTOMLEFT;
else if (xPos >= width() - boundaryWidth && yPos >= height() - boundaryWidth)//右下角
*result = HTBOTTOMRIGHT;
else if (xPos < boundaryWidth) //左边
*result = HTLEFT;
else if (xPos >= width() - boundaryWidth) //右边
*result = HTRIGHT;
else if (yPos < boundaryWidth) //上边
*result = HTTOP;
else if (yPos >= height() - boundaryWidth) //下边
*result = HTBOTTOM;
else
return false;
}
return false;
}
头文件
#include <QMouseEvent>
#include <windows.h>
#include <windowsx.h>