DragAbleDialog.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439
  1. /**
  2. * 叶海辉
  3. * QQ群121376426
  4. * http://blog.yundiantech.com/
  5. */
  6. #include "DragAbleDialog.h"
  7. #include "ui_DragAbleDialog.h"
  8. #include <QDesktopWidget>
  9. #include <QMouseEvent>
  10. #include <QTimer>
  11. #include <QDebug>
  12. #define MARGINS 1 //窗体边框
  13. //鼠标实现改变窗口大小
  14. #define PADDING 6
  15. enum Direction { UP=0, DOWN, LEFT, RIGHT, LEFTTOP, LEFTBOTTOM, RIGHTBOTTOM, RIGHTTOP, NONE };
  16. DragAbleDialog::DragAbleDialog(QWidget *parent) :
  17. QDialog(parent),
  18. ui(new Ui::DragAbleDialog)
  19. {
  20. ui->setupUi(this);
  21. ///定时器用于定制检测鼠标位置,防止鼠标快速移入窗口,没有检测到,导致鼠标箭头呈现拖拉的形状
  22. mTimer = new QTimer;
  23. mTimer->setInterval(1000);
  24. connect(mTimer, &QTimer::timeout, this, &DragAbleDialog::slotTimerTimeOut);
  25. mTimer->start();
  26. ///改变窗体大小相关
  27. isMax = false;
  28. // int w = this->width();
  29. // int h = this->height();
  30. // QRect screenRect = QApplication::desktop()->screenGeometry();//获取设备屏幕大小
  31. // int x = (screenRect.width() - w) / 2;
  32. // int y = (screenRect.height() - h) / 2;
  33. mLocation = this->geometry();
  34. isLeftPressDown = false;
  35. this->dir = NONE;
  36. this->setMouseTracking(true);// 追踪鼠标
  37. ui->widget_frame->setMouseTracking(true);
  38. ui->widget_container->setMouseTracking(true);
  39. this->setFocusPolicy(Qt::ClickFocus);
  40. ui->widget_frame->setContentsMargins(MARGINS,MARGINS,MARGINS,MARGINS);
  41. showBorderRadius(true);
  42. }
  43. DragAbleDialog::~DragAbleDialog()
  44. {
  45. }
  46. QWidget *DragAbleDialog::getContainWidget()
  47. {
  48. return ui->widget_container;
  49. }
  50. void DragAbleDialog::setTitle(QString str)
  51. {
  52. // ui->label_titleName->setText(str);
  53. this->setWindowTitle(str);
  54. }
  55. ////////////改变窗体大小相关
  56. void DragAbleDialog::mouseReleaseEvent(QMouseEvent *event)
  57. {
  58. if(event->button() == Qt::LeftButton)
  59. {
  60. // qDebug()<<__FUNCTION__;
  61. isLeftPressDown = false;
  62. if(dir != NONE)
  63. {
  64. this->releaseMouse();
  65. this->setCursor(QCursor(Qt::ArrowCursor));
  66. }
  67. }
  68. }
  69. void DragAbleDialog::mousePressEvent(QMouseEvent *event)
  70. {
  71. // qDebug()<<__FUNCTION__;
  72. if (event->type() == QEvent::MouseButtonDblClick)
  73. {
  74. if (event->button() == Qt::LeftButton)
  75. {
  76. // if(QApplication::keyboardModifiers() == (Qt::ControlModifier|Qt::ShiftModifier|Qt::AltModifier))
  77. // {
  78. // doChangeFullScreen(); //ctrl + 左键
  79. // doChangeMaxSize();
  80. // }
  81. }
  82. }
  83. switch(event->button())
  84. {
  85. case Qt::LeftButton:
  86. if (isMax || this->isFullScreen()) break;
  87. isLeftPressDown = true;
  88. checkCursorDirect(event->globalPos());
  89. if(dir != NONE)
  90. {
  91. this->mouseGrabber();
  92. mIsResizeMode = true;
  93. }
  94. else
  95. {
  96. dragPosition = event->globalPos() - this->frameGeometry().topLeft();
  97. mIsResizeMode = false;
  98. }
  99. break;
  100. // case Qt::RightButton:
  101. // if (!this->isFullScreen())
  102. // mAction_FullScreen->setText(tr("show fullscreen"));
  103. // else
  104. // mAction_FullScreen->setText(tr("quit fullscreen"));
  105. // mPopMenu->exec(QCursor::pos());
  106. // break;
  107. default:
  108. QWidget::mousePressEvent(event);
  109. }
  110. }
  111. void DragAbleDialog::mouseMoveEvent(QMouseEvent *event)
  112. {
  113. // qDebug()<<__FUNCTION__<<isLeftPressDown;
  114. QPoint gloPoint = event->globalPos();
  115. QRect rect = this->rect();
  116. QPoint tl = mapToGlobal(rect.topLeft());
  117. QPoint rb = mapToGlobal(rect.bottomRight());
  118. if (isMax || this->isFullScreen()) return;
  119. if (!isLeftPressDown)
  120. {
  121. checkCursorDirect(gloPoint);
  122. return;
  123. }
  124. // if(!isLeftPressDown)
  125. // {
  126. // checkCursorDirect(gloPoint);
  127. // }
  128. // else
  129. {
  130. // if(dir != NONE)
  131. if (mIsResizeMode)
  132. {
  133. QRect rMove(tl, rb);
  134. switch(dir) {
  135. case LEFT:
  136. if(rb.x() - gloPoint.x() <= this->minimumWidth())
  137. rMove.setX(tl.x());
  138. else
  139. rMove.setX(gloPoint.x());
  140. break;
  141. case RIGHT:
  142. rMove.setWidth(gloPoint.x() - tl.x());
  143. break;
  144. case UP:
  145. if(rb.y() - gloPoint.y() <= this->minimumHeight())
  146. rMove.setY(tl.y());
  147. else
  148. rMove.setY(gloPoint.y());
  149. break;
  150. case DOWN:
  151. rMove.setHeight(gloPoint.y() - tl.y());
  152. break;
  153. case LEFTTOP:
  154. if(rb.x() - gloPoint.x() <= this->minimumWidth())
  155. rMove.setX(tl.x());
  156. else
  157. rMove.setX(gloPoint.x());
  158. if(rb.y() - gloPoint.y() <= this->minimumHeight())
  159. rMove.setY(tl.y());
  160. else
  161. rMove.setY(gloPoint.y());
  162. break;
  163. case RIGHTTOP:
  164. rMove.setWidth(gloPoint.x() - tl.x());
  165. rMove.setY(gloPoint.y());
  166. break;
  167. case LEFTBOTTOM:
  168. rMove.setX(gloPoint.x());
  169. rMove.setHeight(gloPoint.y() - tl.y());
  170. break;
  171. case RIGHTBOTTOM:
  172. rMove.setWidth(gloPoint.x() - tl.x());
  173. rMove.setHeight(gloPoint.y() - tl.y());
  174. break;
  175. default:
  176. break;
  177. }
  178. this->setGeometry(rMove);
  179. // emit sig_WindowMoved(rMove);
  180. } else {
  181. checkCursorDirect(event->globalPos());
  182. if (dir == NONE && !isMax)
  183. {
  184. QPoint point = event->globalPos() - dragPosition;
  185. QRect mLimitRect = QApplication::desktop()->availableGeometry();
  186. if (point.x() < mLimitRect.x())
  187. point.setX(mLimitRect.x());
  188. if (point.x() > (mLimitRect.x()+mLimitRect.width()-this->width()))
  189. point.setX(mLimitRect.x()+mLimitRect.width()-this->width());
  190. if (point.y() < mLimitRect.y())
  191. point.setY(mLimitRect.y());
  192. if (point.y() > (mLimitRect.y()+mLimitRect.height()-this->height()))
  193. point.setY(mLimitRect.y()+mLimitRect.height()-this->height());
  194. move(point);
  195. }
  196. event->accept();
  197. }
  198. }
  199. // QWidget::mouseMoveEvent(event);、
  200. event->accept();
  201. }
  202. void DragAbleDialog::checkCursorDirect(const QPoint &cursorGlobalPoint)
  203. {
  204. // 获取窗体在屏幕上的位置区域,tl为topleft点,rb为rightbottom点
  205. QRect rect = this->rect();
  206. QPoint tl = mapToGlobal(rect.topLeft());
  207. QPoint rb = mapToGlobal(rect.bottomRight());
  208. int x = cursorGlobalPoint.x();
  209. int y = cursorGlobalPoint.y();
  210. if(tl.x() + PADDING >= x && tl.x() <= x && tl.y() + PADDING >= y && tl.y() <= y) {
  211. // 左上角
  212. dir = LEFTTOP;
  213. this->setCursor(QCursor(Qt::SizeFDiagCursor)); // 设置鼠标形状
  214. } else if(x >= rb.x() - PADDING && x <= rb.x() && y >= rb.y() - PADDING && y <= rb.y()) {
  215. // 右下角
  216. dir = RIGHTBOTTOM;
  217. this->setCursor(QCursor(Qt::SizeFDiagCursor));
  218. } else if(x <= tl.x() + PADDING && x >= tl.x() && y >= rb.y() - PADDING && y <= rb.y()) {
  219. //左下角
  220. dir = LEFTBOTTOM;
  221. this->setCursor(QCursor(Qt::SizeBDiagCursor));
  222. } else if(x <= rb.x() && x >= rb.x() - PADDING && y >= tl.y() && y <= tl.y() + PADDING) {
  223. // 右上角
  224. dir = RIGHTTOP;
  225. this->setCursor(QCursor(Qt::SizeBDiagCursor));
  226. } else if(x <= tl.x() + PADDING && x >= tl.x()) {
  227. // 左边
  228. dir = LEFT;
  229. this->setCursor(QCursor(Qt::SizeHorCursor));
  230. } else if( x <= rb.x() && x >= rb.x() - PADDING) {
  231. // 右边
  232. dir = RIGHT;
  233. this->setCursor(QCursor(Qt::SizeHorCursor));
  234. }else if(y >= tl.y() && y <= tl.y() + PADDING){
  235. // 上边
  236. dir = UP;
  237. this->setCursor(QCursor(Qt::SizeVerCursor));
  238. } else if(y <= rb.y() && y >= rb.y() - PADDING) {
  239. // 下边
  240. dir = DOWN;
  241. this->setCursor(QCursor(Qt::SizeVerCursor));
  242. }else {
  243. // 默认
  244. dir = NONE;
  245. this->setCursor(QCursor(Qt::ArrowCursor));
  246. }
  247. }
  248. void DragAbleDialog::doShowMaxSize()
  249. {
  250. this->show();
  251. this->showMaximized();
  252. this->raise();
  253. ui->widget_frame->setContentsMargins(0,0,0,0); //隐藏边框
  254. showBorderRadius(false);
  255. }
  256. void DragAbleDialog::doShowFullScreen()
  257. {
  258. this->show();
  259. this->showFullScreen();
  260. this->raise();
  261. ui->widget_frame->setContentsMargins(0,0,0,0); //隐藏边框
  262. showBorderRadius(false);
  263. }
  264. void DragAbleDialog::doShowNormal()
  265. {
  266. qDebug()<<__FUNCTION__;
  267. this->show();
  268. this->showNormal();
  269. this->raise();
  270. if (!isMax)
  271. {
  272. ui->widget_frame->setContentsMargins(MARGINS,MARGINS,MARGINS,MARGINS);
  273. showBorderRadius(true);
  274. } else {
  275. ui->widget_frame->setContentsMargins(0,0,0,0);
  276. showBorderRadius(false);
  277. }
  278. }
  279. void DragAbleDialog::showBorderRadius(bool isShow)
  280. {
  281. QString str;
  282. if (isShow)
  283. {
  284. str = QString("QWidget#widget_frame\
  285. {\
  286. border:3px solid rgb(46, 165, 255);\
  287. background-color: rgba(255, 255, 255, 0);\
  288. border-radius:5px;\
  289. }\
  290. QWidget#widget_back\
  291. {\
  292. border-radius:3px;\
  293. }\
  294. QWidget#widget_title\
  295. {\
  296. border-top-right-radius:5px;\
  297. border-top-left-radius:5px;\
  298. }\
  299. QWidget#widget_container\
  300. {\
  301. border-bottom-right-radius:5px;\
  302. border-bottom-left-radius:5px;\
  303. }\
  304. QStackedWidget\
  305. {\
  306. border-bottom-right-radius:5px;\
  307. border-bottom-left-radius:5px;\
  308. }\
  309. QWidget#page_courseList\
  310. {\
  311. border-bottom-right-radius:5px;\
  312. border-bottom-left-radius:5px;\
  313. }");
  314. }
  315. else
  316. {
  317. str = QString("QWidget#widget_frame\
  318. {\
  319. border:3px solid rgb(46, 165, 255);\
  320. background-color: rgba(255, 255, 255, 0);\
  321. border-radius:0px;\
  322. }\
  323. QWidget#widget_back\
  324. {\
  325. border-radius:0px;\
  326. }\
  327. QWidget#widget_title\
  328. {\
  329. border-top-right-radius:0px;\
  330. border-top-left-radius:0px;\
  331. }\
  332. QWidget#widget_container\
  333. {\
  334. border-bottom-right-radius:0px;\
  335. border-bottom-left-radius:0px;\
  336. }\
  337. QStackedWidget\
  338. {\
  339. border-bottom-right-radius:0px;\
  340. border-bottom-left-radius:0px;\
  341. }\
  342. QWidget#page_courseList\
  343. {\
  344. border-bottom-right-radius:0px;\
  345. border-bottom-left-radius:0px;\
  346. }");
  347. }
  348. ui->widget_frame->setStyleSheet(str);
  349. }
  350. void DragAbleDialog::doChangeFullScreen()
  351. {
  352. if (this->isFullScreen())
  353. {
  354. // this->doShowNormal();
  355. // mAction_FullScreen->setText(tr("show fullscreen"));
  356. }
  357. else
  358. {
  359. this->doShowFullScreen();
  360. // mAction_FullScreen->setText(tr("quit fullscreen"));
  361. }
  362. }
  363. void DragAbleDialog::doChangeMaxSize()
  364. {
  365. if (this->isMaximized())
  366. {
  367. // this->doShowNormal();
  368. // mAction_FullScreen->setText(tr("show fullscreen"));
  369. }
  370. else
  371. {
  372. this->doShowMaxSize();
  373. // mAction_FullScreen->setText(tr("quit fullscreen"));
  374. }
  375. }
  376. void DragAbleDialog::slotTimerTimeOut()
  377. {
  378. if (QObject::sender() == mTimer)
  379. {
  380. if (!isLeftPressDown)
  381. checkCursorDirect(QCursor::pos());
  382. }
  383. }