DragAbleWidget.cpp 14 KB

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