selectwidget.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711
  1. #pragma execution_character_set("utf-8")
  2. #include "selectwidget.h"
  3. SelectWidget::SelectWidget(QWidget *parent) : QWidget(parent)
  4. {
  5. drawPoint = false;
  6. pointSize = 10;
  7. padding = pointSize / 2;
  8. borderWidth = 1;
  9. pointColor = QColor(34, 163, 168);
  10. pointStyle = PointStyle::PointStyle_Rect;
  11. m_Hitted = false;
  12. pressed = false;
  13. pressedLeft = false;
  14. pressedRight = false;
  15. pressedTop = false;
  16. pressedBottom = false;
  17. pressedLeftTop = false;
  18. pressedRightTop = false;
  19. pressedLeftBottom = false;
  20. pressedRightBottom = false;
  21. m_StretchDir = STRETCH_DIRECTION::DIR_NONE;
  22. m_pWidget = nullptr;
  23. // 增加:控件的类型的和指针
  24. m_Type = VALUE_TYPE::Type_Unknown;
  25. m_pProperty = nullptr;
  26. // 扩展属性
  27. m_pPropertyEx = nullptr;
  28. //设置鼠标追踪为真,并绑定事件过滤器,可以获取焦点用于按键移动位置
  29. this->setMouseTracking(true);
  30. //安装事件过滤器,识别鼠标拖动和拉伸大小
  31. this->installEventFilter(this);
  32. //设置焦点策略,以便鼠标按下获取焦点并手柄可见
  33. this->setFocusPolicy(Qt::StrongFocus);
  34. }
  35. /// <summary>
  36. /// 拦截所属的控件事件
  37. /// </summary>
  38. /// <param name="watched"></param>
  39. /// <param name="event"></param>
  40. /// <returns></returns>
  41. bool SelectWidget::eventFilter(QObject *watched, QEvent *event)
  42. {
  43. //// 拦截键盘事件
  44. //if (event->type() == QEvent::KeyPress)
  45. //{
  46. // QKeyEvent *keyEvent = dynamic_cast<QKeyEvent *>(event);
  47. //if (keyEvent->key() == Qt::Key_Left)
  48. //{
  49. // this->move(this->pos() - QPoint(1, 0));
  50. //} else if (keyEvent->key() == Qt::Key_Right)
  51. //{
  52. // this->move(this->pos() + QPoint(1, 0));
  53. //} else if (keyEvent->key() == Qt::Key_Up)
  54. //{
  55. // this->move(this->pos() - QPoint(0, 1));
  56. //} else if (keyEvent->key() == Qt::Key_Down)
  57. //{
  58. // this->move(this->pos() + QPoint(0, 1));
  59. //} else
  60. //if (keyEvent->key() == Qt::Key_Delete)
  61. //{
  62. // emit widgetDelete(m_pWidget);
  63. // m_pWidget->deleteLater();
  64. // this->deleteLater();
  65. // m_pWidget = nullptr;
  66. //}
  67. ////重新设置主控件的位置和大小
  68. //if (m_pWidget != nullptr)
  69. //{
  70. // m_pWidget->setGeometry(this->x() + padding, this->y() + padding, this->width() - padding * 2, this->height() - padding * 2);
  71. //}
  72. // return QWidget::eventFilter(watched, event);
  73. //}
  74. QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
  75. if (mouseEvent->type() == QEvent::MouseButtonPress)
  76. {
  77. // qDebug() << "QEvent::MouseButtonPress";
  78. //记住当前控件坐标和宽高以及鼠标按下的坐标
  79. rectX = this->x();
  80. rectY = this->y();
  81. rectW = this->width();
  82. rectH = this->height();
  83. lastPos = mouseEvent->pos();
  84. //判断按下的手柄的区域位置
  85. if (rectLeft.contains(lastPos)) {
  86. pressedLeft = true;
  87. } else if (rectRight.contains(lastPos)) {
  88. pressedRight = true;
  89. } else if (rectTop.contains(lastPos)) {
  90. pressedTop = true;
  91. } else if (rectBottom.contains(lastPos)) {
  92. pressedBottom = true;
  93. } else if (rectLeftTop.contains(lastPos)) {
  94. pressedLeftTop = true;
  95. } else if (rectRightTop.contains(lastPos)) {
  96. pressedRightTop = true;
  97. } else if (rectLeftBottom.contains(lastPos)) {
  98. pressedLeftBottom = true;
  99. } else if (rectRightBottom.contains(lastPos)) {
  100. pressedRightBottom = true;
  101. } else {
  102. pressed = true;
  103. }
  104. m_Hitted = true;
  105. if (m_pWidget != nullptr)
  106. {
  107. emit widgetPressed(m_pWidget);
  108. }
  109. }
  110. // 鼠标移动时
  111. else if (mouseEvent->type() == QEvent::MouseMove)
  112. {
  113. // qDebug() << "QEvent::MouseMove";
  114. //根据当前鼠标位置,计算XY轴移动了多少
  115. QPoint pos = mouseEvent->pos();
  116. int dx = pos.x() - lastPos.x();
  117. int dy = pos.y() - lastPos.y();
  118. // 重置控件被拉伸的方向
  119. m_StretchDir = STRETCH_DIRECTION::DIR_NONE;
  120. //根据按下处的位置判断是否是移动控件还是拉伸控件
  121. if (pressed)
  122. {
  123. QPoint curPos = QPoint(this->x() + dx, this->y() + dy);
  124. // 坐标对齐后再移动
  125. this->alignToGrid(curPos);
  126. this->move(curPos);
  127. }
  128. // 向左拖动
  129. else if (pressedLeft)
  130. {
  131. // 计算拖动后的位置和尺寸
  132. int fixX = this->alignToGrid(this->x() + dx);
  133. int dx2 = fixX - this->x();
  134. int resizeW = this->width() - dx2;
  135. if (this->minimumWidth() <= resizeW)
  136. {
  137. this->setGeometry(fixX, rectY, resizeW, rectH);
  138. m_StretchDir = STRETCH_DIRECTION::DIR_LEFT;
  139. }
  140. }
  141. // 向右拖动
  142. else if (pressedRight)
  143. {
  144. // 重新计算对齐后的右边界坐标
  145. int fixRight = this->alignToGrid(rectX + rectW + dx);
  146. int resizeW = fixRight - rectX;
  147. this->setGeometry(rectX, rectY, resizeW, rectH);
  148. m_StretchDir = STRETCH_DIRECTION::DIR_RIGHT;
  149. }
  150. // 向上拖动
  151. else if (pressedTop)
  152. {
  153. // 计算拖动后的位置和尺寸
  154. int fixY = this->alignToGrid(this->y() + dy);
  155. int dy2 = fixY - this->y();
  156. int resizeH = this->height() - dy2;
  157. if (this->minimumHeight() <= resizeH)
  158. {
  159. this->setGeometry(rectX, fixY, rectW, resizeH);
  160. m_StretchDir = STRETCH_DIRECTION::DIR_TOP;
  161. }
  162. }
  163. // 向下拖动
  164. else if (pressedBottom)
  165. {
  166. // 重新计算对齐后的下边界坐标
  167. int fixBottom = this->alignToGrid(rectY + rectH + dy);
  168. int resizeH = fixBottom - rectY;
  169. this->setGeometry(rectX, rectY, rectW, resizeH);
  170. m_StretchDir = STRETCH_DIRECTION::DIR_BOTTOM;
  171. }
  172. // 向左上拖动
  173. else if (pressedLeftTop)
  174. {
  175. // 计算拖动后的位置和尺寸
  176. int fixX = this->alignToGrid(this->x() + dx);
  177. int dx2 = fixX - this->x();
  178. int resizeW = this->width() - dx2;
  179. // 计算拖动后的位置和尺寸
  180. int fixY = this->alignToGrid(this->y() + dy);
  181. int dy2 = fixY - this->y();
  182. int resizeH = this->height() - dy2;
  183. if (this->minimumWidth() <= resizeW)
  184. {
  185. this->setGeometry(fixX, this->y(), resizeW, resizeH);
  186. m_StretchDir = STRETCH_DIRECTION::DIR_LEFTTOP;
  187. }
  188. if (this->minimumHeight() <= resizeH)
  189. {
  190. this->setGeometry(this->x(), fixY, resizeW, resizeH);
  191. m_StretchDir = STRETCH_DIRECTION::DIR_LEFTTOP;
  192. }
  193. }
  194. // 向右上拖动
  195. else if (pressedRightTop)
  196. {
  197. // 重新计算对齐后的右边界坐标
  198. int fixRight = this->alignToGrid(rectX + rectW + dx);
  199. int resizeW = fixRight - rectX;
  200. // 计算拖动后的位置和尺寸
  201. int fixY = this->alignToGrid(this->y() + dy);
  202. int dy2 = fixY - this->y();
  203. int resizeH = this->height() - dy2;
  204. if (this->minimumHeight() <= resizeH)
  205. {
  206. this->setGeometry(this->x(), fixY, resizeW, resizeH);
  207. m_StretchDir = STRETCH_DIRECTION::DIR_RIGHTTOP;
  208. }
  209. }
  210. // 向左下拖动
  211. else if (pressedLeftBottom)
  212. {
  213. // 计算拖动后的位置和尺寸
  214. int fixX = this->alignToGrid(this->x() + dx);
  215. int dx2 = fixX - this->x();
  216. int resizeW = this->width() - dx2;
  217. // 重新计算对齐后的下边界坐标
  218. int fixBottom = this->alignToGrid(rectY + rectH + dy);
  219. int resizeH = fixBottom - rectY;
  220. if (this->minimumWidth() <= resizeW)
  221. {
  222. this->setGeometry(fixX, this->y(), resizeW, resizeH);
  223. m_StretchDir = STRETCH_DIRECTION::DIR_LEFTBOTTOM;
  224. }
  225. if (this->minimumHeight() <= resizeH)
  226. {
  227. this->setGeometry(this->x(), this->y(), resizeW, resizeH);
  228. m_StretchDir = STRETCH_DIRECTION::DIR_LEFTBOTTOM;
  229. }
  230. }
  231. // 向右下拖动
  232. else if (pressedRightBottom)
  233. {
  234. // 重新计算对齐后的右边界坐标
  235. int fixRight = this->alignToGrid(rectX + rectW + dx);
  236. int resizeW = fixRight - rectX;
  237. // 重新计算对齐后的下边界坐标
  238. int fixBottom = this->alignToGrid(rectY + rectH + dy);
  239. int resizeH = fixBottom - rectY;
  240. this->setGeometry(this->x(), this->y(), resizeW, resizeH);
  241. m_StretchDir = STRETCH_DIRECTION::DIR_RIGHTBOTTOM;
  242. }
  243. // 防止鼠标没有做任何操作,控件却被移动的情况
  244. if (m_Hitted)
  245. {
  246. //重新设置主控件的位置和大小
  247. if (m_pWidget != nullptr)
  248. {
  249. m_pWidget->setGeometry(this->x() + padding, this->y() + padding, this->width() - padding * 2, this->height() - padding * 2);
  250. }
  251. }
  252. }
  253. // 鼠标释放时,发送鼠标释放信号
  254. else if (mouseEvent->type() == QEvent::MouseButtonRelease)
  255. {
  256. m_Hitted = false;
  257. pressed = false;
  258. pressedLeft = false;
  259. pressedRight = false;
  260. pressedTop = false;
  261. pressedBottom = false;
  262. pressedLeftTop = false;
  263. pressedRightTop = false;
  264. pressedLeftBottom = false;
  265. pressedRightBottom = false;
  266. // 重置控件被拉伸的方向
  267. m_StretchDir = STRETCH_DIRECTION::DIR_NONE;
  268. if (m_pWidget != nullptr)
  269. {
  270. emit widgetRelease(m_pWidget);
  271. }
  272. }
  273. return QWidget::eventFilter(watched, event);
  274. }
  275. /// <summary>
  276. /// 在区域改变时计算对应的锚点区域
  277. /// </summary>
  278. /// <param name=""></param>
  279. void SelectWidget::resizeEvent(QResizeEvent *)
  280. {
  281. // qDebug() << "SelectWidget::resizeEvent";
  282. //重新计算八个锚点的区域,锚点区域的作用还有就是计算鼠标坐标是否在某一个区域内
  283. double width = this->width();
  284. double height = this->height();
  285. //左侧锚点区域
  286. rectLeft = QRectF(0, int( height / 2.0 - pointSize / 2.0), pointSize, pointSize);
  287. //上侧锚点区域
  288. rectTop = QRectF(int(width / 2 - pointSize / 2), 0, pointSize, pointSize);
  289. //右侧锚点区域
  290. rectRight = QRectF(int(width - pointSize),int( height / 2 - pointSize / 2), pointSize, pointSize);
  291. //下侧锚点区域
  292. rectBottom = QRectF(int(width / 2 - pointSize / 2), height - pointSize, pointSize, pointSize);
  293. //左上角锚点区域
  294. rectLeftTop = QRectF(0, 0, pointSize, pointSize);
  295. //右上角锚点区域
  296. rectRightTop = QRectF(int(width - pointSize), 0, pointSize, pointSize);
  297. //左下角锚点区域
  298. rectLeftBottom = QRectF(0, int(height - pointSize), pointSize, pointSize);
  299. //右下角锚点区域
  300. rectRightBottom = QRectF(width - pointSize, height - pointSize, pointSize, pointSize);
  301. }
  302. /// <summary>
  303. /// 在鼠标拖拽时显示对应的鼠标
  304. /// </summary>
  305. /// <param name="e"></param>
  306. void SelectWidget::mouseMoveEvent(QMouseEvent *e)
  307. {
  308. // qDebug() << "SelectWidget::mouseMoveEvent";
  309. // 计算当前鼠标位置是否在某个区域内,自动更新鼠标形状
  310. // 2022-9-8,由于目前处于自动对齐状态,矩形区域并非和鼠标位置完全吻合,所以此处要把锚点判断区域扩大
  311. QRectF rectLeftTmp = rectLeft.adjusted(-3, -3, 3, 3);
  312. QRectF rectTopTmp = rectTop.adjusted(-3, -3, 3, 3);
  313. QRectF rectRightTmp = rectRight.adjusted(-3, -3, 3, 3);
  314. QRectF rectBottomTmp = rectBottom.adjusted(-3, -3, 3, 3);
  315. QRectF rectLeftTopTmp = rectLeftTop.adjusted(-3, -3, 3, 3);
  316. QRectF rectRightTopTmp = rectRightTop.adjusted(-3, -3, 3, 3);
  317. QRectF rectLeftBottomTmp = rectLeftBottom.adjusted(-3, -3, 3, 3);
  318. QRectF rectRightBottomTmp = rectRightBottom.adjusted(-3, -3, 3, 3);
  319. QPoint p = e->pos();
  320. if (rectLeftTmp.contains(p))
  321. {
  322. this->setCursor(Qt::SizeHorCursor);
  323. }
  324. else if (rectTopTmp.contains(p))
  325. {
  326. this->setCursor(Qt::SizeVerCursor);
  327. }
  328. else if (rectRightTmp.contains(p))
  329. {
  330. this->setCursor(Qt::SizeHorCursor);
  331. }
  332. else if (rectBottomTmp.contains(p))
  333. {
  334. this->setCursor(Qt::SizeVerCursor);
  335. }
  336. else if (rectLeftTopTmp.contains(p))
  337. {
  338. this->setCursor(Qt::SizeFDiagCursor);
  339. }
  340. else if (rectRightTopTmp.contains(p))
  341. {
  342. this->setCursor(Qt::SizeBDiagCursor);
  343. }
  344. else if (rectLeftBottomTmp.contains(p))
  345. {
  346. this->setCursor(Qt::SizeBDiagCursor);
  347. }
  348. else if (rectRightBottomTmp.contains(p))
  349. {
  350. this->setCursor(Qt::SizeFDiagCursor);
  351. }
  352. else
  353. {
  354. this->setCursor(Qt::ArrowCursor);
  355. }
  356. if (m_Hitted)
  357. {
  358. // 发出控件移动信号
  359. emit widgetMove(m_pWidget);
  360. // 2022-9-16,如果同时处于拉伸控件状态的话,还需要同时发送拉伸消息
  361. if (m_StretchDir != STRETCH_DIRECTION::DIR_NONE)
  362. {
  363. emit widgetStretch(m_pWidget, m_StretchDir);
  364. }
  365. }
  366. }
  367. /// <summary>
  368. /// 进行拖拽边框和锚点的绘制
  369. /// </summary>
  370. /// <param name=""></param>
  371. void SelectWidget::paintEvent(QPaintEvent * )
  372. {
  373. if (!drawPoint) {
  374. return;
  375. }
  376. QPainter painter(this);
  377. painter.setRenderHints(QPainter::Antialiasing);
  378. painter.setPen(Qt::NoPen);
  379. painter.setBrush(pointColor);
  380. if (pointStyle == PointStyle::PointStyle_Rect)
  381. {
  382. drawRect(&painter);
  383. }
  384. else if (pointStyle == PointStyle::PointStyle_Circle)
  385. {
  386. drawCircle(&painter);
  387. }
  388. if (borderWidth > 0)
  389. {
  390. drawBorder(&painter);
  391. }
  392. }
  393. /// <summary>
  394. /// 绘制矩形的锚点
  395. /// </summary>
  396. /// <param name="painter"></param>
  397. void SelectWidget::drawRect(QPainter *painter)
  398. {
  399. //逐个绘制 左上角点+顶边中间点+右上角点+左边中间点+右边中间点+左下角点+底边中间点+右下角点
  400. painter->save();
  401. painter->drawRect(rectLeft);
  402. painter->drawRect(rectRight);
  403. painter->drawRect(rectTop);
  404. painter->drawRect(rectBottom);
  405. painter->drawRect(rectLeftTop);
  406. painter->drawRect(rectRightTop);
  407. painter->drawRect(rectLeftBottom);
  408. painter->drawRect(rectRightBottom);
  409. painter->restore();
  410. }
  411. /// <summary>
  412. /// 绘制圆形的锚点
  413. /// </summary>
  414. /// <param name="painter"></param>
  415. void SelectWidget::drawCircle(QPainter *painter)
  416. {
  417. //逐个绘制 左上角点+顶边中间点+右上角点+左边中间点+右边中间点+左下角点+底边中间点+右下角点
  418. painter->save();
  419. painter->drawEllipse(rectLeft);
  420. painter->drawEllipse(rectRight);
  421. painter->drawEllipse(rectTop);
  422. painter->drawEllipse(rectBottom);
  423. painter->drawEllipse(rectLeftTop);
  424. painter->drawEllipse(rectRightTop);
  425. painter->drawEllipse(rectLeftBottom);
  426. painter->drawEllipse(rectRightBottom);
  427. painter->restore();
  428. }
  429. /// <summary>
  430. /// 获取用于拖拽的边框
  431. /// </summary>
  432. /// <param name="painter"></param>
  433. void SelectWidget::drawBorder(QPainter *painter)
  434. {
  435. painter->save();
  436. QPen pen;
  437. pen.setWidth(borderWidth);
  438. pen.setColor(pointColor);
  439. painter->setPen(pen);
  440. painter->setBrush(Qt::NoBrush);
  441. QRectF borderRect(pointSize / 2, pointSize / 2, width() - pointSize, height() - pointSize);
  442. painter->drawRect(borderRect);
  443. painter->restore();
  444. }
  445. bool SelectWidget::getDrawPoint() const
  446. {
  447. return this->drawPoint;
  448. }
  449. int SelectWidget::getPadding() const
  450. {
  451. return this->padding;
  452. }
  453. int SelectWidget::getBorderWidth() const
  454. {
  455. return this->borderWidth;
  456. }
  457. int SelectWidget::getPointSize() const
  458. {
  459. return this->pointSize;
  460. }
  461. QColor SelectWidget::getPointColor() const
  462. {
  463. return this->pointColor;
  464. }
  465. SelectWidget::PointStyle SelectWidget::getPointStyle() const
  466. {
  467. return this->pointStyle;
  468. }
  469. QWidget *SelectWidget::getWidget() const
  470. {
  471. return m_pWidget;
  472. }
  473. QSize SelectWidget::sizeHint() const
  474. {
  475. return QSize(200, 200);
  476. }
  477. QSize SelectWidget::minimumSizeHint() const
  478. {
  479. return QSize(30, 30);
  480. }
  481. /// <summary>
  482. /// 2022-10-21 直接移动控件和外边框的位置(目前用于Redo体系中直接移动控件)
  483. /// </summary>
  484. /// <param name="newPos"></param>
  485. void SelectWidget::updatePos(const QPoint& newPos)
  486. {
  487. // 移动内嵌控件
  488. this->m_pWidget->move(newPos);
  489. // 移动选中外框
  490. this->move(this->m_pWidget->pos() - QPoint(padding, padding));
  491. }
  492. /// <summary>
  493. /// 2022-10-21 直接缩放控件和外边框(目前用于Redo体系中直接缩放控件)
  494. /// </summary>
  495. /// <param name="newGeometry"></param>
  496. void SelectWidget::updateGeometry(const QRect& newGeometry)
  497. {
  498. // 设置内嵌控件
  499. m_pWidget->setGeometry(newGeometry);
  500. // 设置选中外框
  501. this->setGeometry(
  502. newGeometry.x() - padding,
  503. newGeometry.y() - padding,
  504. newGeometry.width() + padding * 2,
  505. newGeometry.height() + padding * 2
  506. );
  507. // this->setGeometry(this->x(), this->y(), resizeW, resizeH);
  508. // m_pWidget->setGeometry(this->x() + padding, this->y() + padding, this->width() - padding * 2, this->height() - padding * 2);
  509. }
  510. void SelectWidget::setDrawPoint(bool drawPoint)
  511. {
  512. if (this->drawPoint != drawPoint) {
  513. this->drawPoint = drawPoint;
  514. update();
  515. }
  516. }
  517. void SelectWidget::setPadding(int padding)
  518. {
  519. if (this->padding != padding) {
  520. this->padding = padding;
  521. update();
  522. }
  523. }
  524. void SelectWidget::setBorderWidth(int borderWidth)
  525. {
  526. if (this->borderWidth != borderWidth) {
  527. this->borderWidth = borderWidth;
  528. update();
  529. }
  530. }
  531. void SelectWidget::setPointSize(int pointSize)
  532. {
  533. if (this->pointSize != pointSize) {
  534. this->pointSize = pointSize;
  535. update();
  536. }
  537. }
  538. void SelectWidget::setPointColor(const QColor &pointColor)
  539. {
  540. if (this->pointColor != pointColor) {
  541. this->pointColor = pointColor;
  542. update();
  543. }
  544. }
  545. void SelectWidget::setPointStyle(const SelectWidget::PointStyle &pointStyle)
  546. {
  547. if (this->pointStyle != pointStyle) {
  548. this->pointStyle = pointStyle;
  549. update();
  550. }
  551. }
  552. /// <summary>
  553. /// 将指定的控件与本控件绑定,并且计算边框尺寸
  554. /// </summary>
  555. /// <param name="widget"></param>
  556. void SelectWidget::setWidget(QWidget *widget)
  557. {
  558. this->m_pWidget = widget;
  559. this->m_pWidget->setVisible(true);
  560. this->setVisible(true);
  561. // 修正一下控件位置,自动对齐到网格
  562. int fixX = this->alignToGrid(this->m_pWidget->x()) + padding;
  563. int fixY = this->alignToGrid(this->m_pWidget->y()) + padding;
  564. this->m_pWidget->move(fixX, fixY);
  565. //设置最小尺寸
  566. this->setMinimumSize(50, 20);
  567. //设置当前窗体大小为跟随窗体的大小增加部分
  568. this->resize(this->m_pWidget->size() + QSize(padding * 2, padding * 2));
  569. //将当前窗体移到偏移位置
  570. this->move(this->m_pWidget->pos() - QPoint(padding, padding));
  571. }
  572. /// <summary>
  573. /// 自动对齐控件(针对Point)
  574. /// </summary>
  575. void SelectWidget::alignToGrid(QPoint& pt)
  576. {
  577. int nGridSize = 10;
  578. // 按四舍五规则来取整,如果采用和Grid一样的方式 std::ceil 向上取整的话,操作会比较奇怪
  579. int dstX = std::round((double)pt.x() / nGridSize) * nGridSize - padding;
  580. int dstY = std::round((double)pt.y() / nGridSize) * nGridSize - padding;
  581. pt.setX(dstX);
  582. pt.setY(dstY);
  583. }
  584. /// <summary>
  585. /// 自动对齐控件(针对单个坐标)
  586. /// </summary>
  587. int SelectWidget::alignToGrid(int x)
  588. {
  589. int nGridSize = 10;
  590. // 按四舍五规则来取整,如果采用和Grid一样的方式 std::ceil 向上取整的话,操作会比较奇怪
  591. int dstX = std::round((double)x / nGridSize) * nGridSize - padding;
  592. return dstX;
  593. }