JMouseMonitorThread.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. // *****************************************************************************
  2. // 版权所有(C)2023~2099 上海骄成超声波技术有限公司
  3. // 保留所有权利
  4. // *****************************************************************************
  5. // 作者 : 杨坚
  6. // 版本 : 1.0
  7. // 功能说明:
  8. // 鼠标监控-全局的,可能后面还有其他地方使用,所以..
  9. // *****************************************************************************
  10. #include "JMouseMonitorThread.h"
  11. #include <qDebug>
  12. JMouseMonitorThread::JMouseMonitorThread(QObject* parent /*= nullptr*/)
  13. : QThread(parent),
  14. m_locked(false),
  15. m_running(true)
  16. {
  17. }
  18. void JMouseMonitorThread::setLockCenter(const QPoint center)
  19. {
  20. QMutexLocker locker(&m_mutex);
  21. m_lockCenter = center;
  22. m_locked = true;
  23. }
  24. void JMouseMonitorThread::unlock()
  25. {
  26. QMutexLocker locker(&m_mutex);
  27. m_locked = false;
  28. }
  29. void JMouseMonitorThread::stop()
  30. {
  31. m_running = false;
  32. wait();
  33. }
  34. void JMouseMonitorThread::ConvertUIClickToImagePixel(int uiX, int uiY, int& imageX, int& imageY)
  35. {
  36. int uiwidth = 493;//imageLabel->width(); 480 493
  37. int uiheight = 493;// imageLabel->height();360
  38. int imagewidth = 640;
  39. int imageheight = 480;
  40. // 步骤1:转换为左上原点坐标系
  41. float uiX_topLeft = uiX + uiwidth / 2.0f;
  42. float uiY_topLeft = uiY + uiheight / 2.0f; // UI的Y轴向下为正
  43. // 步骤2:计算缩放比例
  44. float scaleX = (float)imagewidth / uiwidth; // 640/480 ≈ 1.333
  45. float scaleY = (float)imageheight / uiheight; // 480/360 ≈ 1.333
  46. // 步骤3:映射到原始图像
  47. int imageXA = (int)(uiX_topLeft * scaleX);
  48. int imageYA = (int)(uiY_topLeft * scaleY);
  49. // 确保坐标在图像范围内
  50. imageX = std::max(0, std::min(imagewidth - 1, imageXA));
  51. imageY = std::max(0, std::min(imageheight - 1, imageYA));
  52. }
  53. void JMouseMonitorThread::ConvertUIClickToImagePixel2(int uiX, int uiY, int& imageX, int& imageY)
  54. {
  55. const int uiWidth = 493; // UI控件实际宽度
  56. const int uiHeight = 493; // UI控件实际高度
  57. const int imgWidth = 640; // 原始图像宽度
  58. const int imgHeight = 480; // 原始图像高度
  59. // 1. 计算保持宽高比的缩放比例
  60. const float scale = std::min(
  61. static_cast<float>(uiWidth) / imgWidth,
  62. static_cast<float>(uiHeight) / imgHeight
  63. );
  64. // 2. 计算实际显示区域尺寸
  65. const int displayWidth = static_cast<int>(imgWidth * scale);
  66. const int displayHeight = static_cast<int>(imgHeight * scale);
  67. // 3. 计算显示区域在控件中的偏移(居中)
  68. const int offsetX = (uiWidth - displayWidth) / 2;
  69. const int offsetY = (uiHeight - displayHeight) / 2;
  70. // 4. 将UI坐标转换为显示区域坐标
  71. const int uiClickX = uiX + uiWidth / 2; // 转换到控件坐标系
  72. const int uiClickY = uiY + uiHeight / 2;
  73. // 5. 有效性检查(点击是否在显示区域内)
  74. const int displayX = std::max(0, std::min(displayWidth - 1, uiClickX - offsetX));
  75. const int displayY = std::max(0, std::min(displayHeight - 1, uiClickY - offsetY));
  76. // 6. 映射到原始图像坐标
  77. imageX = static_cast<int>(displayX / scale);
  78. imageY = static_cast<int>(displayY / scale);
  79. // 最终有效性检查
  80. imageX = std::max(0, std::min(imgWidth - 1, imageX));
  81. imageY = std::max(0, std::min(imgHeight - 1, imageY));
  82. }
  83. void JMouseMonitorThread::run()
  84. {
  85. QPoint lastPos = QCursor::pos();
  86. while (m_running)
  87. {
  88. if (m_locked)
  89. {
  90. QPoint currentPos;
  91. QPoint center;
  92. {
  93. QMutexLocker locker(&m_mutex);
  94. center = m_lockCenter;
  95. }
  96. currentPos = QCursor::pos();
  97. QPoint delta = currentPos - center;
  98. if (delta != QPoint(0, 0))
  99. {
  100. int imageX, imageY;
  101. ConvertUIClickToImagePixel2(delta.x(), delta.y(),imageX, imageY);
  102. //qDebug() << "image POS" << imageX << " " << imageY;
  103. delta.setX(imageX);
  104. delta.setY(imageY);
  105. emit MouseMovedSlg(delta);
  106. emit RequestCursorMoveSlg(center);
  107. }
  108. }
  109. msleep(15);
  110. }
  111. }