QMainwindow的鼠标跟踪事件不触发问题

news/2024/12/22 7:30:19/

一、无边框窗口实现代码

1.1 头文件

class EtcTestTool : public QMainWindow
{Q_OBJECTpublic:EtcTestTool(QWidget *parent = Q_NULLPTR);
private:void InitialUi();//...
protected:void mousePressEvent(QMouseEvent*event)override;void mouseReleaseEvent(QMouseEvent*event)override;void mouseMoveEvent(QMouseEvent*event)override;
private:// 鼠标的 活动范围的枚举enum MousePosition{    /* 这里我们将一个窗口划分为9个区域,分别为左上角(1, 1)、中上(2,1)、右上角(3, 1)左中  (1, 2)、 中间(2, 2)、右中  (3, 2)左下角(1, 3)、中下(2,3)、 右下角(3, 3)10*x+y区分各个区域*/LeftTop = 11,Top = 21,RightTop = 31,Left = 12,Mid = 22,Right = 32,LeftBottom = 13,Bottom = 23,RightBottom = 33};//根据鼠标的设置鼠标样式,用于拉伸void SetMouseCursor(int x, int y);//判断鼠标的区域,用于拉伸int GetMouseRegion(int x, int y);
private:QPoint m_windowsLastPs;QPoint m_mouseLastPs;int m_mouse_press_region = MousePosition::Mid;QPoint m_dragStartPos;bool m_bPressing = false;private:Ui::EtcTestToolClass ui;
};

1.2 实现文件


EtcTestTool::EtcTestTool(QWidget *parent): QMainWindow(parent)
{setWindowFlags(Qt::FramelessWindowHint);ui.setupUi(this);InitialUi();//...}void EtcTestTool::InitialUi()
{//mainwindow的鼠标跟踪事件被子控件遮挡拦截this->setMouseTracking(true);ui.centralWidget->setMouseTracking(true);ui.frame->setMouseTracking(true);ui.frmTitle->setMouseTracking(true);ui.groupBox->setMouseTracking(true);//...}void EtcTestTool::on_btnMin_clicked()
{showMinimized();
}
void EtcTestTool::on_btnMax_clicked()
{if (isMaximized()){showNormal();ui.btnMax->setProperty("Max", false);}else{showMaximized();ui.btnMax->setProperty("Max", true);}ui.btnMax->style()->polish(ui.btnMax);
}void EtcTestTool::on_btnClose_clicked()
{close();
}void EtcTestTool::mousePressEvent(QMouseEvent*event)
{if (event->button() == Qt::LeftButton){// 如果是鼠标左键// 获取当前窗口位置,以窗口左上角为标定m_windowsLastPs = pos();// 获取鼠标在屏幕的位置  就是全局的坐标 以屏幕左上角为坐标系m_mouseLastPs = event->globalPos();m_bPressing = true;m_mouse_press_region = GetMouseRegion(event->pos().x(), event->pos().y());}QWidget::mousePressEvent(event);
}void EtcTestTool::mouseReleaseEvent(QMouseEvent*event)
{if (event->button() == Qt::LeftButton){m_bPressing = false;}setCursor(QCursor{});QWidget::mousePressEvent(event);
}void EtcTestTool::mouseMoveEvent(QMouseEvent*event)
{// 设置鼠标的形状SetMouseCursor(event->pos().x(), event->pos().y());// 计算的鼠标移动偏移量, 就是鼠标全局坐标 - 减去点击时鼠标坐标QPoint point_offset = event->globalPos() - m_mouseLastPs;if ((event->buttons() == Qt::LeftButton) && m_bPressing){if (m_mouse_press_region == Mid){// 如果鼠标是在窗口的中间位置,就是移动窗口move(m_windowsLastPs + point_offset);}else {// 其他部分 是拉伸窗口// 获取客户区QRect rect = geometry();switch (m_mouse_press_region){// 左上角case LeftTop:rect.setTopLeft(rect.topLeft() + point_offset);break;case Top:rect.setTop(rect.top() + point_offset.y());break;case RightTop:rect.setTopRight(rect.topRight() + point_offset);break;case Right:rect.setRight(rect.right() + point_offset.x());break;case RightBottom:rect.setBottomRight(rect.bottomRight() + point_offset);break;case Bottom:rect.setBottom(rect.bottom() + point_offset.y());break;case LeftBottom:rect.setBottomLeft(rect.bottomLeft() + point_offset);break;case Left:rect.setLeft(rect.left() + point_offset.x());break;default:break;}setGeometry(rect);m_mouseLastPs = event->globalPos();}}QWidget::mousePressEvent(event);
}void EtcTestTool::SetMouseCursor(int x, int y)
{// 鼠标形状对象Qt::CursorShape cursor{};int region = GetMouseRegion(x, y);switch (region){case LeftTop:case RightBottom:cursor = Qt::SizeFDiagCursor; break;case RightTop:case LeftBottom:cursor = Qt::SizeBDiagCursor; break;case Left:case Right:cursor = Qt::SizeHorCursor; break;case Top:case Bottom:cursor = Qt::SizeVerCursor; break;caseMid:cursor = Qt::ArrowCursor; break;default:break;}setCursor(cursor);
}int EtcTestTool::GetMouseRegion(int x, int y)
{int region_x = 0, region_y = 0;// 鼠标的X坐标小于 边界 说明他在最上层区域 第一区域if (x < kMouseBorderSize){region_x = 1;}else if (x > (this->width() - kMouseBorderSize)) {region_x = 3;}else {region_x = 2;}if (y < kMouseBorderSize){region_y = 1;}else if (y > (this->height() - kMouseBorderSize)) {region_y = 3;}else {region_y = 2;}return region_x * 10 + region_y;
}

二、鼠标移动事件无法触发

2.1 现象和原因

        Qt默认鼠标跟踪事件是关闭的,只有按下鼠标左键移动时才会触发;所以需要setMouseTracking(true)开启鼠标追踪事件。但是开启后仍然无法在不按左键情况下触发鼠标移动事件,后发现软件复写的QMainWindow的mouseMoveEvent函数,但是QMainWindow界面被centralWidget和布局的各种widget遮挡导致鼠标移动事件无法触发。

 

2.2 解决方案

解决方案:将QMainWindow的子控件centralWidget等同样开启鼠标跟踪事件setMouseTracking(true),则子控件的鼠标移动事件会通过事件循环传递到父类的QMainWindow中,最终触发QMainWindow的mouseMoveEvent函数。

void EtcTestTool::InitialUi()
{
    //mainwindow的鼠标跟踪事件被子控件遮挡拦截,
    this->setMouseTracking(true);
    ui.centralWidget->setMouseTracking(true);
    ui.frame->setMouseTracking(true);
    ui.frmTitle->setMouseTracking(true);
    ui.groupBox->setMouseTracking(true);
    //...
}


http://www.ppmy.cn/news/1557135.html

相关文章

智能座舱进阶-应用框架层-Jetpack主要组件

Jetpack的分类 1. DataBinding&#xff1a;以声明方式将可观察数据绑定到界面元素&#xff0c;通常和ViewModel配合使用。 2. Lifecycle&#xff1a;用于管理Activity和Fragment的生命周期&#xff0c;可帮助开发者生成更易于维护的轻量级代码。 3. LiveData: 在底层数据库更…

2024年云计算的发展趋势如何?

2024年云计算的发展趋势 在这个瞬息万变的科技时代&#xff0c;你是否也曾想过&#xff0c;云计算的发展究竟对我们每一个人意味着什么&#xff1f;它不仅是存储和计算能力的提升&#xff0c;更是整个行业的未来构建与转型之道。接下来&#xff0c;我们将一起探索2024年云计算…

Linux创建普通用户和修改主机名

创建修改用户名和用户组 工作组相关命令 功能命令说明切换用户su username注销用户logout新建用户adduser username 创建用户并分配到用户组useradd -g test username 设置用户密码passwd username查看某一用户w username查看登录用户w查看登陆用户并显示IPwho查看登录历史…

重拾设计模式--适配器模式

文章目录 适配器模式&#xff08;Adapter Pattern&#xff09;概述适配器模式UML图适配器模式的结构目标接口&#xff08;Target&#xff09;&#xff1a;适配器&#xff08;Adapter&#xff09;&#xff1a;被适配者&#xff08;Adaptee&#xff09;&#xff1a; 作用&#xf…

课上测试:商用密码标准实现

文章目录 完成下面任务&#xff08;29分&#xff09;1 在 Ubuntu 或 openEuler 中完成任务&#xff08;推荐openEuler&#xff09;2 简述 GM/T0009 4种数据转换的功能&#xff0c;根据你的理解&#xff0c;每种转换功能给出至少一个例子 &#xff08;8分&#xff09;3 参考课程…

EGO Swarm翻译

目录 摘要 Ⅰ 介绍 Ⅱ 相关工作 A . 单四旋翼局部规划 B . 拓扑规划 C. 分布式无人机集群 Ⅲ 基于梯度的局部规划隐式拓扑轨迹生成 A.无需ESDF梯度的局部路径规划 B.隐式拓扑轨迹生成 Ⅳ 无人机集群导航 A 机间避碰 B. 定位漂移补偿 C. 从深度图像中去除agent Ⅴ …

适用于.net的操作excel的库

目录 目录 知识点概要 知识点具体说明(使用步骤、解释) 使用场景及示例 1. EPPlus 2. NPOI 3. ClosedXml 4. SpreadsheetLight 5.ExcelDataReader 开源库 6. ExcelDataWriter 总结 知识点概要 使用Excel来导入和导出数据&#xff0c;在日常工作中使用频率是相当高的&…

3D造型软件solvespace在windows下的编译

3D造型软件solvespace在windows下的编译 在逛开源社区的时候发现了几款开源CAD建模软件&#xff0c;一直囿于没有合适的建模软件&#xff0c;虽然了解了很多的模拟分析软件&#xff0c;却不能使之成为整体的解决方案&#xff0c;从而无法产生价值。opencascad之流虽然可行&…