ImageWidget.cpp 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. #include "ImageWidget.h"
  2. #include "ui_ImageWidget.h"
  3. #include <QPainter>
  4. #include <QDebug>
  5. #include <QMouseEvent>
  6. ImageWidget::ImageWidget(QWidget *parent) :
  7. QWidget(parent),
  8. imageOffset(0, 0),
  9. isDrawing(false),
  10. isDragging(false),
  11. ui(new Ui::ImageWidget)
  12. {
  13. ui->setupUi(this);
  14. pen.setColor(Qt::red);
  15. pen.setWidth(2);
  16. }
  17. ImageWidget::~ImageWidget()
  18. {
  19. delete ui;
  20. }
  21. void ImageWidget::setPixmap(const QPixmap& newPixmap)
  22. {
  23. this->m_pixmap = newPixmap;
  24. imageOffset = QPoint(0, 0); // 重置图片偏移量为(0, 0)
  25. setCursor(Qt::ArrowCursor);
  26. update(); // 触发重绘
  27. }
  28. void ImageWidget::setPixmapAndPoint(const QPixmap& pixmap, double previousScaleFactor, qreal scaleFactor, QPoint mousePos) {
  29. this->m_pixmap = pixmap;
  30. QPointF imagePos = (mousePos - imageOffset) / previousScaleFactor;
  31. imageOffset = mousePos - imagePos * scaleFactor;
  32. update();
  33. }
  34. void ImageWidget::clearPixmap()
  35. {
  36. this->m_pixmap = QPixmap(); // 将 pixmap 设置为空
  37. update(); // 触发重绘
  38. }
  39. void ImageWidget::paintEvent(QPaintEvent *event)
  40. {
  41. QPainter painter(this);
  42. if (!m_pixmap.isNull())
  43. //{
  44. // // 限制图片偏移量,确保图片不会被拖动到视图外
  45. // int pixmapWidth = pixmap.width();
  46. // int pixmapHeight = pixmap.height();
  47. // int widgetWidth = width();
  48. // int widgetHeight = height();
  49. // // 限制横向偏移量,确保图片不会超出左边或右边
  50. // if (pixmapWidth < widgetWidth)
  51. // {
  52. // imageOffset.setX(0); // 如果图片宽度小于控件宽度,居中显示
  53. // }
  54. // else
  55. // {
  56. // // 图片左边界不能超出控件左边,右边界不能超出控件右边
  57. // imageOffset.setX(qMin(0.0, qMax(static_cast<qreal>(widgetWidth - pixmapWidth), imageOffset.x())));
  58. // }
  59. // // 限制纵向偏移量,确保图片不会超出上边或下边
  60. // if (pixmapHeight < widgetHeight)
  61. // {
  62. // imageOffset.setY(0); // 如果图片高度小于控件高度,居中显示
  63. // }
  64. // else
  65. // {
  66. // // 图片上边界不能超出控件上边,下边界不能超出控件下边
  67. // imageOffset.setY(qMin(0.0, qMax(static_cast<qreal>(widgetHeight - pixmapHeight), imageOffset.y())));
  68. // }
  69. {
  70. // 限制图片偏移量,确保图片不会被拖动到视图外
  71. int pixmapWidth = m_pixmap.width();
  72. int pixmapHeight = m_pixmap.height();
  73. int widgetWidth = width();
  74. int widgetHeight = height();
  75. // 限制横向偏移量,确保图片不会超出左边或右边
  76. if (pixmapWidth < widgetWidth)
  77. {
  78. imageOffset.setX(0); // 如果图片宽度小于控件宽度,居中显示
  79. }
  80. else
  81. {
  82. // 图片左边界不能超出控件左边,右边界不能超出控件右边
  83. imageOffset.setX(qMin(0.0, qMax(static_cast<qreal>(widgetWidth - pixmapWidth), imageOffset.x())));
  84. }
  85. // 限制纵向偏移量,确保图片不会超出上边或下边
  86. if (pixmapHeight < widgetHeight)
  87. {
  88. imageOffset.setY(0); // 如果图片高度小于控件高度,居中显示
  89. }
  90. else
  91. {
  92. // 图片上边界不能超出控件上边,下边界不能超出控件下边
  93. imageOffset.setY(qMin(0.0, qMax(static_cast<qreal>(widgetHeight - pixmapHeight), imageOffset.y())));
  94. }
  95. painter.drawPixmap(imageOffset.x(), imageOffset.y(), m_pixmap);
  96. QRect targetRect = { 493,493,493,493 };
  97. if (m_nSingleCameraOperationWnd)
  98. {
  99. targetRect = { 794,794,794,794 };
  100. }
  101. drawCross(&painter, targetRect);
  102. painter.setPen(pen);
  103. for (const auto& line : lines)
  104. {
  105. painter.drawLine(line);
  106. }
  107. painter.setPen(pen);
  108. for (const auto& line : lines)
  109. {
  110. painter.drawLine(line);
  111. }
  112. //DrawCrossWithScale(&painter, pixmapWidth, pixmapHeight, { 476,300 }, { 300,300 });
  113. }
  114. QWidget::paintEvent(event);
  115. }
  116. void ImageWidget::mousePressEvent(QMouseEvent *event)
  117. {
  118. if (event->button() == Qt::LeftButton)
  119. {
  120. lastMousePos = event->pos();
  121. isDragging = true;
  122. setCursor(Qt::BlankCursor);
  123. }
  124. else if (isDrawing && event->button() == Qt::RightButton)
  125. {
  126. lastPoint = event->pos();
  127. unsetCursor();
  128. }
  129. QWidget::mousePressEvent(event);
  130. }
  131. void ImageWidget::mouseMoveEvent(QMouseEvent *event) {
  132. if (isDragging && (event->buttons() & Qt::LeftButton)) {
  133. QPoint delta = event->pos() - lastMousePos; // 计算鼠标移动的偏移量
  134. imageOffset += delta; // 更新图片的偏移量
  135. lastMousePos = event->pos(); // 更新鼠标位置
  136. update();
  137. }else if (isDrawing && event->buttons() & Qt::RightButton) {
  138. lines.append(QLine(lastPoint, event->pos()));
  139. lastPoint = event->pos();
  140. update();
  141. }
  142. QWidget::mouseMoveEvent(event);
  143. }
  144. void ImageWidget::mouseReleaseEvent(QMouseEvent *event) {
  145. if (event->button() == Qt::LeftButton) {
  146. isDragging = false; // 重置正在拖动的标志
  147. setCursor(Qt::ArrowCursor);
  148. }else if (isDrawing && event->button() == Qt::RightButton) {
  149. lines.append(QLine(lastPoint, event->pos()));
  150. lastPoint = event->pos();
  151. unsetCursor();
  152. }
  153. QWidget::mouseReleaseEvent(event);
  154. }
  155. void ImageWidget::mouseDoubleClickEvent(QMouseEvent *event){
  156. if ((event->type() == QEvent::MouseButtonDblClick)&&(event->button() == Qt::LeftButton)) {
  157. // 恢复原始图像
  158. sendDoubleClicksignal();
  159. }
  160. QWidget::mouseDoubleClickEvent(event);
  161. }
  162. void ImageWidget::DrawCrossWithScale(QPainter* painter, double dImgWidth, double dImgHeight, const QSize& sourceImageSize, const QPointF& sourceImagePosition)
  163. {
  164. QPen pen;
  165. pen.setWidth(1);
  166. pen.setBrush(Qt::yellow);
  167. painter->setPen(pen);
  168. const double drX = dImgWidth / 2;
  169. const double drY = dImgHeight / 2;
  170. const int nLineSpace = 20;
  171. const int shortLineLen = 15;
  172. const int longLineLen = 35;
  173. // 计算缩放比例
  174. double power = 1.0;
  175. auto drawLines = [&, power](double start, double end, int step, bool horizontal) {
  176. for (int i = 0; ; ++i) { // 使用无限循环,并通过条件跳出
  177. int increase = i * nLineSpace;
  178. if (increase > std::abs(end)) break; // 检查是否超过边界
  179. int lineLength = (i % 5 == 0 && i != 0) ? longLineLen : shortLineLen;
  180. QPointF ptX1, ptY1, ptX2, ptY2;
  181. if (horizontal) {
  182. // Horizontal lines
  183. ptX1 = QPointF((start + increase - sourceImagePosition.x()) * power, (drY - lineLength - sourceImagePosition.y()) * power);
  184. ptY1 = QPointF((start + increase - sourceImagePosition.x()) * power, (drY + lineLength - sourceImagePosition.y()) * power);
  185. ptX2 = QPointF((start - increase - sourceImagePosition.x()) * power, (drY - lineLength - sourceImagePosition.y()) * power);
  186. ptY2 = QPointF((start - increase - sourceImagePosition.x()) * power, (drY + lineLength - sourceImagePosition.y()) * power);
  187. }
  188. else {
  189. // Vertical lines
  190. ptX1 = QPointF((drX - lineLength - sourceImagePosition.x()) * power, (start + increase - sourceImagePosition.y()) * power);
  191. ptY1 = QPointF((drX + lineLength - sourceImagePosition.x()) * power, (start + increase - sourceImagePosition.y()) * power);
  192. ptX2 = QPointF((drX - lineLength - sourceImagePosition.x()) * power, (start - increase - sourceImagePosition.y()) * power);
  193. ptY2 = QPointF((drX + lineLength - sourceImagePosition.x()) * power, (start - increase - sourceImagePosition.y()) * power);
  194. }
  195. painter->drawLine(ptX1, ptY1);
  196. painter->drawLine(ptX2, ptY2);
  197. }
  198. };
  199. // Draw the cross with scale on both sides of the center
  200. drawLines(dImgWidth / 2.0, dImgWidth, nLineSpace, true); // Right and Left side
  201. drawLines(dImgHeight / 2.0, dImgHeight, nLineSpace, false); // Top and Bottom side
  202. }
  203. void ImageWidget::drawCross(QPainter* painter, QRect rect)
  204. {
  205. QPen pen;
  206. pen.setWidth(3);
  207. pen.setBrush(Qt::yellow);
  208. painter->setPen(pen);
  209. painter->drawLine(rect.width() / 2, 0, rect.width() / 2, rect.height());
  210. painter->drawLine(0, rect.height() / 2, rect.width(), rect.height() / 2);
  211. }
  212. void ImageWidget::setIsDrawing(bool value) {
  213. isDrawing = value;
  214. if (isDrawing) {
  215. setCursor(Qt::CrossCursor);
  216. }
  217. else {
  218. unsetCursor();
  219. }
  220. }
  221. void ImageWidget::clearDrawing() {
  222. lines.clear(); // 清空线条列表
  223. update();
  224. }