【QT入门】 鼠标按下和移动事件实现无边框窗口拖动

往期回顾:

【QT入门】 QScrollArea实际运用之导航栏设计-CSDN博客

【QT入门】 QScrollArea实际运用之滑动Widget设计-CSDN博客

【QT入门】QWidget类的简单介绍-CSDN博客

【QT入门】 鼠标按下和移动事件实现无边框窗口拖动

一、如何实现无边框窗口拖动

1、思路:

主要是用到Qt里的两个函数,分别是mousePressEvent鼠标按下事件和mouseMoveEvent鼠标移动事件,通过这两个函数的结合使用来实现,同时其中要用到好几个坐标位置,需要区分理解好。

2、主要知识点:

先熟悉几个主要的知识点:

2.1设置无边框窗口
复制代码
this->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowMinMaxButtonsHint); 

设置为了无边框窗口和实现点击图标最大最小化。

2.2坐标位置
复制代码
private:
    QPoint diff_pos; //鼠标和窗口的相对位移
    QPoint window_pos; //窗口的绝对位置
    QPoint mouse_pos; //鼠标的绝对位置

这里一定要搞清楚这几个位置点,否则很容易被绕晕。

窗口位置

this->pos()窗口左, 上角相对于桌面左,上角

鼠标位置

event->pos()是鼠标相对于应用程序的位置

event->globalPos()相对于桌面原点的位置,绝对位置

2.3鼠标按下事件
复制代码
void  mousePressEvent(QMouseEvent* event)  override;

void MainWidget::mousePressEvent(QMouseEvent* event)
{
    mouse_pos = event->globalPos();
    window_pos = this->pos();
    diff_pos = mouse_pos - window_pos;

}

当鼠标按下时,会触发该函数。通过 QMouseEvent 对象获取当前鼠标的全局位置 mouse_pos 和窗口的当前位置 window_pos。计算鼠标按下时的位置与窗口位置的差异,存储在diff_pos中,以便在移动鼠标时使用。

因为鼠标按下时这个窗口和鼠标的相对位置之差是一个固定值,之后只需要保持这个固定值不变,就可以实现窗口随鼠标移动而移动。

2.4鼠标移动事件
复制代码
 void  mouseMoveEvent(QMouseEvent* event) override;

void MainWidget::mouseMoveEvent(QMouseEvent * event)
{
    QPoint pos = event->globalPos();

    this->move(pos - diff_pos);
}

void move(const QPoint &);可以用来移动窗口、控件

当鼠标移动时,会触发该函数。通过 QMouseEvent 对象获取当前鼠标的全局位置 pos。

diff_pos 存储了鼠标按下时的位置与窗口位置的差异。通过 this->move(pos - diff_pos),将窗口移动到新的位置,即鼠标当前位置减去差异值。

3、实现原理:

由于在mousePressEvent 函数中记录了鼠标按下时的位置和窗口位置的差异,这样在鼠标移动时就可以根据这个差异来调整窗口的位置,实现拖动效果。

而在 mouseMoveEvent 函数中,通过计算当前鼠标位置与初始鼠标位置的差值,实时更新窗口的位置,从而实现窗口跟随鼠标移动的效果。

最后综合就实现了鼠标按下可以进行无边框窗口的拖动。

4、完整示例代码:

4.1MainWidget.h
复制代码
#pragma once

#include <QtWidgets/QWidget>


class MainWidget : public QWidget
{
    Q_OBJECT

public:
    MainWidget(QWidget *parent = Q_NULLPTR);

private:
    void mousePressEvent(QMouseEvent* event) override;
    void mouseMoveEvent(QMouseEvent* event) override;

private:
    QPoint diff_pos;  // 鼠标和窗口的相对位移
    QPoint window_pos;
    QPoint mouse_pos;
};
4.2MainWidget.cpp
复制代码
#include "MainWidget.h"
#include <QMouseEvent>

MainWidget::MainWidget(QWidget *parent)
    : QWidget(parent)
{
    this->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowMinMaxButtonsHint);
}

void MainWidget::mousePressEvent(QMouseEvent* event)
{
    mouse_pos = event->globalPos();
    window_pos = this->pos();
    diff_pos = mouse_pos - window_pos;
}

void MainWidget::mouseMoveEvent(QMouseEvent* event)
{
    QPoint pos = event->globalPos();
    //this->move(pos);
    this->move(pos - diff_pos);
}

都看到这里了,点个赞再走呗朋友~

加油吧,预祝大家变得更强!

相关推荐
妙为4 小时前
银河麒麟V4下编译Qt5.12.12源码
c++·qt·国产化·osg3.6.5·osgearth3.2·银河麒麟v4
史迪仔01127 小时前
[QML] QML IMage图像处理
开发语言·前端·javascript·c++·qt
小樱花的樱花12 小时前
打造高效记事本:UI设计到功能实现
开发语言·c++·qt·ui
丁劲犇12 小时前
QMetaObject的invokeMethod异步阻塞调用在MCPServer开发中的巧妙应用
qt·ai·agent·异步·阻塞·mcp·mcp server
m0_4972141514 小时前
Qt事件系统
开发语言·qt
秋月的私语15 小时前
遥感影像拼接线优化工具:基于Qt+GDAL+OpenCV的从零到一实践
开发语言·qt·opencv
姓刘的哦15 小时前
Qt自定义控件
开发语言·qt
AlanW16 小时前
Qt Model/View 框架完全指南:从入门到性能优化
qt
艾莉丝努力练剑19 小时前
【QT】Qt常用控件与布局管理深度解析:从原理到实践的架构思考
linux·运维·服务器·开发语言·网络·qt·架构
Z文的博客19 小时前
嵌入式 ARM 设备交叉编译 mosquitto 2.0.20 (完整 TLS 支持) 详细教程 TRAE全程辅助,没敲一行代码
qt·mqtt·嵌入式·ai编程·mosquitto·嵌入式linux·trae