当前位置:   article > 正文

QT 无标题栏窗口的拖动和拉伸_this->installeventfilter(this)

this->installeventfilter(this)

如下2种方案,2种方案都不完美(拉伸窗口都会抖动),但是如果一定要使用,强烈推荐第1种方案(可减小拉伸时窗口抖动

方案1:

  1. //this->installEventFilter(this);
  2. bool MainWindow::eventFilter(QObject *watched, QEvent *event)
  3. {
  4. if (watched == this){
  5. static bool mousePressed = false;
  6. static QPoint last_globalPos;
  7. static QPoint last_pos;
  8. static bool isLeft = false, isTop = false, isRight = false, isBottom = false;
  9. static bool isInDragResizeArea = true;
  10. const int EDGE_SIZE = 10;
  11. const int TITLE_HEIGHT = 40;
  12. QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
  13. if (mouseEvent->type() == QEvent::MouseButtonPress) {
  14. if (mouseEvent->button() == Qt::LeftButton) {
  15. mousePressed = true;
  16. last_pos = pos();
  17. last_globalPos = mouseEvent->globalPos();
  18. if (mouseEvent->pos().x() < 5)
  19. isLeft = true;
  20. else isLeft = false;
  21. if (mouseEvent->pos().x() <= this->width() && (mouseEvent->pos().x() + EDGE_SIZE) >= this->width() )
  22. isRight = true;
  23. else isRight = false;
  24. if (mouseEvent->pos().y() < 5)
  25. isTop = true;
  26. else isTop = false;
  27. if (mouseEvent->pos().y() <= this->height() && (mouseEvent->pos().y() + EDGE_SIZE) >= this->height())
  28. isBottom = true;
  29. else isBottom = false;
  30. }
  31. } else if (mouseEvent->type() == QEvent::MouseButtonRelease) {
  32. mousePressed = false;
  33. } else if (mouseEvent->type() == QEvent::MouseMove) {
  34. if (!mousePressed){
  35. if (mouseEvent->pos().x() < 5)
  36. isLeft = true;
  37. else isLeft = false;
  38. if (mouseEvent->pos().x() <= this->width() && (mouseEvent->pos().x() + EDGE_SIZE) >= this->width() )
  39. isRight = true;
  40. else isRight = false;
  41. if (mouseEvent->pos().y() < 5)
  42. isTop = true;
  43. else isTop = false;
  44. if (mouseEvent->pos().y() <= this->height() && (mouseEvent->pos().y() + EDGE_SIZE) >= this->height())
  45. isBottom = true;
  46. else isBottom = false;
  47. }
  48. QPoint point_offset = mouseEvent->globalPos() - last_globalPos;
  49. //先判断是否在拖拽区
  50. isInDragResizeArea = true;
  51. if (isLeft){
  52. if (isTop) setCursor(Qt::SizeFDiagCursor);
  53. else if (isBottom) setCursor(Qt::SizeBDiagCursor);
  54. else setCursor(Qt::SizeHorCursor);
  55. }
  56. else if (isRight){
  57. if (isTop) setCursor(Qt::SizeBDiagCursor);
  58. else if (isBottom) setCursor(Qt::SizeFDiagCursor);
  59. else setCursor(Qt::SizeHorCursor);
  60. }
  61. else if (isTop || isBottom){
  62. setCursor(Qt::SizeVerCursor);
  63. }
  64. else {
  65. isInDragResizeArea = false;
  66. setCursor(Qt::ArrowCursor);
  67. }
  68. if (mousePressed) {
  69. if (isInDragResizeArea){
  70. QRect rect = geometry();
  71. if (isLeft && isTop)
  72. rect.setTopLeft(rect.topLeft() + point_offset);
  73. else if (isTop)
  74. rect.setTop(rect.top() + point_offset.y());
  75. else if (isTop && isRight)
  76. rect.setTopRight(rect.topRight() + point_offset);
  77. else if (isRight)
  78. rect.setRight(rect.right() + point_offset.x());
  79. else if (isRight && isBottom)
  80. rect.setBottomRight(rect.bottomRight() + point_offset);
  81. else if (isBottom)
  82. rect.setBottom(rect.bottom() + point_offset.y());
  83. else if (isBottom && isLeft)
  84. rect.setBottomLeft(rect.bottomLeft() + point_offset);
  85. else if (isLeft)
  86. rect.setLeft(rect.left() + point_offset.x());
  87. this->setGeometry(rect);
  88. last_globalPos = mouseEvent->globalPos();
  89. }
  90. else{
  91. if (mouseEvent->pos().y() <= TITLE_HEIGHT) {
  92. this->move(point_offset + last_pos);
  93. }
  94. }
  95. return true;
  96. }
  97. }
  98. else if (mouseEvent->type() == QEvent::MouseButtonDblClick){
  99. if (mouseEvent->pos().y() <= TITLE_HEIGHT){
  100. if (this->windowState() & Qt::WindowMaximized) {
  101. this->showNormal();
  102. }
  103. else {
  104. this->showMaximized();
  105. }
  106. }
  107. }
  108. }
  109. return QMainWindow::eventFilter(watched, event);
  110. }

方案2:

  1. #ifdef Q_OS_WIN
  2. #include "windowsx.h"
  3. #pragma comment (lib,"user32.lib")
  4. #endif
  5. #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
  6. bool MainWindow::nativeEvent(const QByteArray &eventType, void *message, qintptr *result)
  7. #else
  8. bool MainWindow::nativeEvent(const QByteArray &eventType, void *message, long *result)
  9. #endif
  10. {
  11. MSG* msg = static_cast<MSG*>(message);
  12. if (msg->message == WM_NCHITTEST) {
  13. *result = 0;
  14. const int EDGE_SIZE = 8;
  15. const int TITLE_HEIGHT = 40;
  16. RECT winrect;
  17. GetWindowRect(reinterpret_cast<HWND>(winId()), &winrect);
  18. long x = GET_X_LPARAM(msg->lParam);
  19. long y = GET_Y_LPARAM(msg->lParam);
  20. // 判断鼠标位置是否在拉伸区域内
  21. if (y < winrect.top + EDGE_SIZE) {
  22. *result = HTTOP;
  23. }
  24. if (y > winrect.bottom - EDGE_SIZE) {
  25. *result = HTBOTTOM;
  26. }
  27. if (x < winrect.left + EDGE_SIZE) {
  28. *result = HTLEFT;
  29. }
  30. if (x > winrect.right - EDGE_SIZE) {
  31. *result = HTRIGHT;
  32. }
  33. if (y < winrect.top + EDGE_SIZE && x < winrect.left + EDGE_SIZE) {
  34. *result = HTTOPLEFT;
  35. }
  36. if (y < winrect.top + EDGE_SIZE && x > winrect.right - EDGE_SIZE) {
  37. *result = HTTOPRIGHT;
  38. }
  39. if (y > winrect.bottom - EDGE_SIZE && x < winrect.left + EDGE_SIZE) {
  40. *result = HTBOTTOMLEFT;
  41. }
  42. if (y > winrect.bottom - EDGE_SIZE && x > winrect.right - EDGE_SIZE) {
  43. *result = HTBOTTOMRIGHT;
  44. }
  45. if (*result != 0) {
  46. return true;
  47. }
  48. }
  49. return QWidget::nativeEvent(eventType, message, result);
  50. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/354318
推荐阅读
相关标签
  

闽ICP备14008679号