1. #ifndef MOVEWIDGET_H
  2. #define MOVEWIDGET_H
  3.  
  4. #include <QWidget>
  5. #include <QEvent>
  6.  
  7. class MoveWidget : public QWidget
  8. {
  9. Q_OBJECT
  10.  
  11. public:
  12. MoveWidget(QWidget *parent);
  13. ~MoveWidget();
  14. void setResizable(bool bResiable); //设置是否可以缩放
  15. void setMargin(const int &); //设置鼠标距离界面边缘的范围
  16.  
  17. protected:
  18. virtual bool eventFilter(QObject *, QEvent *);
  19.  
  20. private:
  21. void changeMouseStyle(const QPoint &);
  22. private:
  23. bool m_bResizable; //界面是否可以缩放
  24. int m_iMarginWidth; //鼠标位置相对于界面边缘的距离
  25. bool m_bPressed; //鼠标是否按下
  26. QPoint m_ptPressPos;//鼠标按下时的位置
  27. };
  28.  
  29. #endif // MOVEWIDGET_H

  

  1. #include "MoveWidget.h"
  2. #include <QHoverEvent>
  3.  
  4. enum MouseStyle{ NORMAL, TOP, BOTTOM, LEFT, RIGHT, TOPLEFT, BOTTOMLEFT, BOTTOMRIGHT, TOPRIGHT } mouseStyle;
  5.  
  6. MoveWidget::MoveWidget(QWidget *parent)
  7. : QWidget(parent)
  8. , m_bResizable(true)
  9. , m_iMarginWidth(6)
  10. , m_bPressed(false)
  11. , m_ptPressPos(0, 0)
  12. {
  13. this->setWindowFlags(Qt::FramelessWindowHint | Qt::Window);
  14. this->setAttribute(Qt::WA_Hover);
  15. this->installEventFilter(this);
  16. }
  17.  
  18. MoveWidget::~MoveWidget()
  19. {
  20.  
  21. }
  22.  
  23. bool MoveWidget::eventFilter(QObject *, QEvent *event)
  24. {
  25. switch (event->type())
  26. {
  27. //[1]鼠标在界面上移动
  28. case QEvent::HoverMove:
  29. {
  30. QHoverEvent *hoverEvent = dynamic_cast<QHoverEvent *>(event);
  31. if (!m_bPressed)
  32. {
  33. changeMouseStyle(hoverEvent->pos());
  34. }
  35. else
  36. {
  37. if (mouseStyle == NORMAL)
  38. {
  39. this->move(this->mapToGlobal(hoverEvent->pos()) - m_ptPressPos);
  40. return true;
  41. }
  42. QPoint ptGlobalPos = this->mapToGlobal(hoverEvent->pos());
  43. QPoint ptTopLeft = this->frameGeometry().topLeft();
  44. QPoint ptBottomRight = this->frameGeometry().bottomRight();
  45. switch (mouseStyle)
  46. {
  47. case TOP:
  48. if (ptBottomRight.y() - ptGlobalPos.y() > this->minimumHeight())
  49. {
  50. ptTopLeft.setY(ptGlobalPos.y());
  51. }
  52. else
  53. {
  54. ptTopLeft.setY(ptBottomRight.y() - this->minimumHeight());
  55. }
  56. break;
  57. case BOTTOM:
  58. if (ptGlobalPos.y() - ptTopLeft.y() > this->minimumHeight())
  59. {
  60. ptBottomRight.setY(ptGlobalPos.y());
  61. }
  62. else
  63. {
  64. ptBottomRight.setY(ptTopLeft.y() + this->minimumHeight());
  65. }
  66. break;
  67. case LEFT:
  68. if (ptBottomRight.x() - ptGlobalPos.x() > this->minimumWidth())
  69. {
  70. ptTopLeft.setX(ptGlobalPos.x());
  71. }
  72. else
  73. {
  74. ptTopLeft.setX(ptBottomRight.x() - this->minimumWidth());
  75. }
  76. break;
  77. case RIGHT:
  78. if (ptGlobalPos.x() - ptTopLeft.x() > this->minimumWidth())
  79. {
  80. ptBottomRight.setX(ptGlobalPos.x());
  81. }
  82. else
  83. {
  84. ptBottomRight.setX(ptTopLeft.x() + this->minimumWidth());
  85. }
  86. break;
  87. case TOPLEFT:
  88. if (ptBottomRight.x() - ptGlobalPos.x() > this->minimumWidth())
  89. {
  90. ptTopLeft.setX(ptGlobalPos.x());
  91. }
  92. else
  93. {
  94. ptTopLeft.setX(ptBottomRight.x() - this->minimumWidth());
  95. }
  96. if (ptBottomRight.y() - ptGlobalPos.y() > this->minimumHeight())
  97. {
  98. ptTopLeft.setY(ptGlobalPos.y());
  99. }
  100. else
  101. {
  102. ptTopLeft.setY(ptBottomRight.y() - this->minimumHeight());
  103. }
  104. break;
  105. case BOTTOMLEFT:
  106. if (ptBottomRight.x() - ptGlobalPos.x() > this->minimumWidth())
  107. {
  108. ptTopLeft.setX(ptGlobalPos.x());
  109. }
  110. else
  111. {
  112. ptTopLeft.setX(ptBottomRight.x() - this->minimumWidth());
  113. }
  114. if (ptGlobalPos.y() - ptTopLeft.y() > this->minimumHeight())
  115. {
  116. ptBottomRight.setY(ptGlobalPos.y());
  117. }
  118. else
  119. {
  120. ptBottomRight.setY(ptTopLeft.y() + this->minimumHeight());
  121. }
  122. break;
  123. case BOTTOMRIGHT:
  124. if (ptGlobalPos.x() - ptTopLeft.x() > this->minimumWidth())
  125. {
  126. ptBottomRight.setX(ptGlobalPos.x());
  127. }
  128. else
  129. {
  130. ptBottomRight.setX(ptTopLeft.x() + this->minimumWidth());
  131. }
  132. if (ptGlobalPos.y() - ptTopLeft.y() > this->minimumHeight())
  133. {
  134. ptBottomRight.setY(ptGlobalPos.y());
  135. }
  136. else
  137. {
  138. ptBottomRight.setY(ptTopLeft.y() + this->minimumHeight());
  139. }
  140. break;
  141. case TOPRIGHT:
  142. if (ptBottomRight.y() - ptGlobalPos.y() > this->minimumHeight())
  143. {
  144. ptTopLeft.setY(ptGlobalPos.y());
  145. }
  146. else
  147. {
  148. ptTopLeft.setY(ptBottomRight.y() - this->minimumHeight());
  149. }
  150. if (ptGlobalPos.x() - ptTopLeft.x() > this->minimumWidth())
  151. {
  152. ptBottomRight.setX(ptGlobalPos.x());
  153. }
  154. else
  155. {
  156. ptBottomRight.setX(ptTopLeft.x() + this->minimumWidth());
  157. }
  158. break;
  159. default:
  160. break;
  161. }
  162. this->setGeometry(QRect(ptTopLeft, ptBottomRight));
  163. }
  164. return true;
  165. }
  166. break;
  167. //[1]end 鼠标在界面上移动
  168.  
  169. //[2]鼠标按下
  170. case QEvent::MouseButtonPress:
  171. {
  172. m_bPressed = true;
  173. QMouseEvent *mouseEvent = dynamic_cast<QMouseEvent *>(event);
  174. m_ptPressPos = mouseEvent->globalPos() - this->frameGeometry().topLeft();
  175. }
  176. break;
  177. //[2]end 鼠标按下
  178.  
  179. //[3]鼠标松开
  180. case QEvent::MouseButtonRelease:
  181. {
  182. m_bPressed = false;
  183. QMouseEvent *mouseEvent = dynamic_cast<QMouseEvent *>(event);
  184. changeMouseStyle(mouseEvent->pos());
  185. }
  186. break;
  187. //[3]end 鼠标松开
  188.  
  189. default:
  190. break;
  191. }
  192. return false;
  193. }
  194.  
  195. void MoveWidget::changeMouseStyle(const QPoint &ptMousePos)
  196. {
  197. if (!m_bResizable)
  198. {
  199. setCursor(Qt::ArrowCursor);//正常样式
  200. mouseStyle = NORMAL;
  201. return;
  202. }
  203. int iPosX = ptMousePos.x();
  204. int iPosY = ptMousePos.y();
  205.  
  206. int iWidth = this->width();
  207. int iHeight = this->height();
  208. if (iPosX >= iWidth - m_iMarginWidth && iPosX <= iWidth)
  209. {
  210. setCursor(Qt::SizeHorCursor);//右
  211. if (iPosY >= 0 && iPosY <= m_iMarginWidth)
  212. {
  213. setCursor(Qt::SizeBDiagCursor);//右上
  214. mouseStyle = TOPRIGHT;
  215. return;
  216. }
  217. if (iPosY >= iHeight - m_iMarginWidth && iPosY <= iHeight)
  218. {
  219. setCursor(Qt::SizeFDiagCursor);//右下
  220. mouseStyle = BOTTOMRIGHT;
  221. return;
  222. }
  223. mouseStyle = RIGHT;
  224. return;
  225. }
  226.  
  227. if (iPosX >= 0 && iPosX <= m_iMarginWidth)
  228. {
  229. setCursor(Qt::SizeHorCursor);//左
  230. if (iPosY >= 0 && iPosY <= m_iMarginWidth)
  231. {
  232. setCursor(Qt::SizeFDiagCursor);//左上
  233. mouseStyle = TOPLEFT;
  234. return;
  235. }
  236. if (iPosY >= iHeight - m_iMarginWidth && iPosY <= iHeight)
  237. {
  238. setCursor(Qt::SizeBDiagCursor);//左下
  239. mouseStyle = BOTTOMLEFT;
  240. return;
  241. }
  242. mouseStyle = LEFT;
  243. return;
  244. }
  245.  
  246. if (iPosY >= 0 && iPosY <= m_iMarginWidth)
  247. {
  248. setCursor(Qt::SizeVerCursor);//上
  249. mouseStyle = TOP;
  250. return;
  251. }
  252. if (iPosY >= iHeight - m_iMarginWidth && iPosY <= iHeight)
  253. {
  254. setCursor(Qt::SizeVerCursor);//下
  255. mouseStyle = BOTTOM;
  256. return;
  257. }
  258. setCursor(Qt::ArrowCursor);//正常样式
  259. mouseStyle = NORMAL;
  260. return;
  261. }
  262.  
  263. void MoveWidget::setResizable(bool bResiable)
  264. {
  265. m_bResizable = bResiable;
  266. }
  267.  
  268. void MoveWidget::setMargin(const int &iWidth)
  269. {
  270. m_iMarginWidth = iWidth;
  271. }

  

Qt——鼠标拖动缩放窗口源码的更多相关文章

  1. qt 鼠标拖动窗口放大缩小

    // 鼠标拖动 具体实现void mouseMoveEvent(QMouseEvent * pEvent) { if (pEvent->buttons() & Qt::LeftButto ...

  2. Bootstrap 模态窗口源码分析

    前言: bootstrap的 js插件的源码写的非常好,也算是编写jquery插件的模范写法,本来还想大篇详细的分析一下呢,唉,没时间啊,很早之前看过的源码了,现在贴在了博客上, 300来行的代码,其 ...

  3. AndroidTv Home界面实现原理(二)——Leanback 库的主页卡位缩放动画源码解析

    先看个效果图: 上一篇中,我们留了问题,在 Tv Home 界面这种很常见聚焦卡位放大动画效果,我们这一篇就来看看 Leanback 库是怎么实现的. 如果要我们自己实现的话,思路应该不难,就是写个放 ...

  4. Qt creator中文输入—fctix-qt5 源码编译 libfcitxplatforminputcontextplugin.so

    fctix-qt5 的源码有两个地方可以下载: wget https://download.fcitx-im.org/fcitx-qt5/fcitx-qt5-1.0.5.tar.xztar -xJf ...

  5. iOS电商常见动画与布局、微信悬浮窗、音乐播放器、歌词解析、拖动视图等源码

    iOS精选源码 MXScroll 介绍 混合使用UIScrollView ios 电商demo(实现各种常见动画效果和页面布局) 一行代码集成微信悬浮窗 可拖动,大小的视图,可放置在屏幕边缘. 在使用 ...

  6. QT:轻松获取网页源码

    获取网页源码的小例子,代码很简单,就不多作解释了. 不过一定要注意网页的编码问题,否则会出现乱码的!!! #include <QtCore> #include <QtNetwork& ...

  7. 40.qt quick- 高仿微信实现局域网聊天V4版本(支持gif动图表情包、消息聊天、拖动缩放窗口)

    在上章37.qt quick- 高仿微信实现局域网聊天V3版本(添加登录界面.UDP校验登录.皮肤更换.3D旋转),我们已经实现了: 添加登录界面. UDP校验登录. 皮肤更换. 3D旋转(主界面和登 ...

  8. qt 鼠标拖动窗口 跳动 解决

    因为获取当前的位置,似乎没有把标题栏的高度记进去. 所以移动前,得考虑到标题栏的高度. 用以下方式获取标题栏高度: QApplication::style()->pixelMetric(QSty ...

  9. Qt——鼠标拖动调整窗口大小

    要求:鼠标移到界面边角时,鼠标样式相应地发生改变. 实现方法一: 重写mouseMoveEvent,如果鼠标没有按下,则根据鼠标在界面上的位置设置鼠标样式,如果鼠标按下,则根据位置判断该怎样调整界面大 ...

随机推荐

  1. Codeforces Round #587 (Div. 3) C题 【判断两个矩形是否完全覆盖一个矩形问题】 {补题 [差点上分系列]}

    C. White Sheet There is a white sheet of paper lying on a rectangle table. The sheet is a rectangle ...

  2. pyecharts v1 版本 学习笔记 折线图,面积图

    折线图 折线图 基本demo import pyecharts.options as opts from pyecharts.charts import Line c = ( Line() .add_ ...

  3. Java中堆内存和栈内存有什么区别

    本文链接:https://blog.csdn.net/wangbo1998/article/details/80379016Java把内存分成两种,一种叫做栈内存,一种叫做堆内存 在函数中定义的一些基 ...

  4. 五十五.ansible概述、ansible基础 、ad-hoc、批量配置管理

    1.环境准备 (自动化工具,批量操作) 6台 2cpu,1.5G以上内存,20G硬盘,1网卡 1.1 基础环境准备 1)启动6台虚拟机,ansible.sh   2)真机配置yum仓库 ]# tar ...

  5. learning express step(十四)

    learning express error handle code: const express = require('express'); const app = express(); const ...

  6. [DK] 化学竞赛的大奖

    https://www.luogu.org/problemnew/show/T16502 无向图  缩点  树的直径  到直径两个端点的距离的较大值 #include <iostream> ...

  7. ECMAScript 提案阶段

    stage0 strawman任何讨论.想法.改变或者还没加到提案的特性都在这个阶段.只有TC39成员可以提交. stage1 proposal (1)产出一个正式的提案. (2)发现潜在的问题,例如 ...

  8. mysql建表问题

    PUBLIC Stack Overflow Tags Users Jobs TeamsQ&A for workLearn More   MySQL error: The maximum col ...

  9. 【做题记录】AtCoder AGC做题记录

    做一下AtCoder的AGC锻炼一下思维吧 目前已做题数: 75 总共题数: 239 每一场比赛后面的字母是做完的题,括号里是写完题解的题 AGC001: ABCDEF (DEF) AGC002: A ...

  10. 取出easyui的datagrid的总数

    var grid = $('#datagrid'); var options = grid.datagrid('getPager').data("pagination").opti ...