DragAbleWidget.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464
  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. case Qt::LeftButton:
  87. if (isMax || this->isFullScreen()) break;
  88. isLeftPressDown = true;
  89. checkCursorDirect(event->globalPos());
  90. if(dir != NONE) {
  91. this->mouseGrabber();
  92. } else {
  93. dragPosition = event->globalPos() - this->frameGeometry().topLeft();
  94. }
  95. break;
  96. // case Qt::RightButton:
  97. // if (!this->isFullScreen())
  98. // mAction_FullScreen->setText(tr("show fullscreen"));
  99. // else
  100. // mAction_FullScreen->setText(tr("quit fullscreen"));
  101. // mPopMenu->exec(QCursor::pos());
  102. // break;
  103. default:
  104. QWidget::mousePressEvent(event);
  105. }
  106. }
  107. void DragAbleWidget::mouseMoveEvent(QMouseEvent *event)
  108. {
  109. // qDebug()<<__FUNCTION__;
  110. if (isMax || this->isFullScreen()) return;
  111. QPoint gloPoint = event->globalPos();
  112. QRect rect = this->rect();
  113. QPoint tl = mapToGlobal(rect.topLeft());
  114. QPoint rb = mapToGlobal(rect.bottomRight());
  115. if(!isLeftPressDown) {
  116. checkCursorDirect(gloPoint);
  117. } else {
  118. if(dir != NONE) {
  119. QRect rMove(tl, rb);
  120. switch(dir) {
  121. case LEFT:
  122. if(rb.x() - gloPoint.x() <= this->minimumWidth())
  123. rMove.setX(tl.x());
  124. else
  125. rMove.setX(gloPoint.x());
  126. break;
  127. case RIGHT:
  128. rMove.setWidth(gloPoint.x() - tl.x());
  129. break;
  130. case UP:
  131. if(rb.y() - gloPoint.y() <= this->minimumHeight())
  132. rMove.setY(tl.y());
  133. else
  134. rMove.setY(gloPoint.y());
  135. break;
  136. case DOWN:
  137. rMove.setHeight(gloPoint.y() - tl.y());
  138. break;
  139. case LEFTTOP:
  140. if(rb.x() - gloPoint.x() <= this->minimumWidth())
  141. rMove.setX(tl.x());
  142. else
  143. rMove.setX(gloPoint.x());
  144. if(rb.y() - gloPoint.y() <= this->minimumHeight())
  145. rMove.setY(tl.y());
  146. else
  147. rMove.setY(gloPoint.y());
  148. break;
  149. case RIGHTTOP:
  150. rMove.setWidth(gloPoint.x() - tl.x());
  151. rMove.setY(gloPoint.y());
  152. break;
  153. case LEFTBOTTOM:
  154. rMove.setX(gloPoint.x());
  155. rMove.setHeight(gloPoint.y() - tl.y());
  156. break;
  157. case RIGHTBOTTOM:
  158. rMove.setWidth(gloPoint.x() - tl.x());
  159. rMove.setHeight(gloPoint.y() - tl.y());
  160. break;
  161. default:
  162. break;
  163. }
  164. this->setGeometry(rMove);
  165. // emit sig_WindowMoved(rMove);
  166. } else {
  167. checkCursorDirect(event->globalPos());
  168. if (dir == NONE && !isMax)
  169. {
  170. QPoint point = event->globalPos() - dragPosition;
  171. QRect mLimitRect = QApplication::desktop()->availableGeometry();
  172. if (point.x() < mLimitRect.x())
  173. point.setX(mLimitRect.x());
  174. if (point.x() > (mLimitRect.x()+mLimitRect.width()-this->width()))
  175. point.setX(mLimitRect.x()+mLimitRect.width()-this->width());
  176. if (point.y() < mLimitRect.y())
  177. point.setY(mLimitRect.y());
  178. if (point.y() > (mLimitRect.y()+mLimitRect.height()-this->height()))
  179. point.setY(mLimitRect.y()+mLimitRect.height()-this->height());
  180. move(point);
  181. }
  182. event->accept();
  183. }
  184. }
  185. // QWidget::mouseMoveEvent(event);、
  186. event->accept();
  187. }
  188. void DragAbleWidget::checkCursorDirect(const QPoint &cursorGlobalPoint)
  189. {
  190. // 获取窗体在屏幕上的位置区域,tl为topleft点,rb为rightbottom点
  191. QRect rect = this->rect();
  192. QPoint tl = mapToGlobal(rect.topLeft());
  193. QPoint rb = mapToGlobal(rect.bottomRight());
  194. int x = cursorGlobalPoint.x();
  195. int y = cursorGlobalPoint.y();
  196. if(tl.x() + PADDING >= x && tl.x() <= x && tl.y() + PADDING >= y && tl.y() <= y) {
  197. // 左上角
  198. dir = LEFTTOP;
  199. this->setCursor(QCursor(Qt::SizeFDiagCursor)); // 设置鼠标形状
  200. } else if(x >= rb.x() - PADDING && x <= rb.x() && y >= rb.y() - PADDING && y <= rb.y()) {
  201. // 右下角
  202. dir = RIGHTBOTTOM;
  203. this->setCursor(QCursor(Qt::SizeFDiagCursor));
  204. } else if(x <= tl.x() + PADDING && x >= tl.x() && y >= rb.y() - PADDING && y <= rb.y()) {
  205. //左下角
  206. dir = LEFTBOTTOM;
  207. this->setCursor(QCursor(Qt::SizeBDiagCursor));
  208. } else if(x <= rb.x() && x >= rb.x() - PADDING && y >= tl.y() && y <= tl.y() + PADDING) {
  209. // 右上角
  210. dir = RIGHTTOP;
  211. this->setCursor(QCursor(Qt::SizeBDiagCursor));
  212. } else if(x <= tl.x() + PADDING && x >= tl.x()) {
  213. // 左边
  214. dir = LEFT;
  215. this->setCursor(QCursor(Qt::SizeHorCursor));
  216. } else if( x <= rb.x() && x >= rb.x() - PADDING) {
  217. // 右边
  218. dir = RIGHT;
  219. this->setCursor(QCursor(Qt::SizeHorCursor));
  220. }else if(y >= tl.y() && y <= tl.y() + PADDING){
  221. // 上边
  222. dir = UP;
  223. this->setCursor(QCursor(Qt::SizeVerCursor));
  224. } else if(y <= rb.y() && y >= rb.y() - PADDING) {
  225. // 下边
  226. dir = DOWN;
  227. this->setCursor(QCursor(Qt::SizeVerCursor));
  228. }else {
  229. // 默认
  230. dir = NONE;
  231. this->setCursor(QCursor(Qt::ArrowCursor));
  232. }
  233. }
  234. void DragAbleWidget::doShowFullScreen()
  235. {
  236. this->show();
  237. this->showFullScreen();
  238. this->raise();
  239. ui->widget_frame->setContentsMargins(0,0,0,0); //隐藏边框
  240. showBorderRadius(false);
  241. ui->btnMenu_Max->setIcon(QIcon(":/image/shownormalbtn.png"));
  242. ui->widget_title->hide(); //隐藏标题栏
  243. // ui->verticalLayout_titleWidget_Back->removeWidget(ui->widget_title);
  244. // ui->widget_title->setParent(NULL);
  245. // ui->widget_title->setWindowFlags(Qt::FramelessWindowHint|Qt::WindowStaysOnTopHint|Qt::Tool|Qt::X11BypassWindowManagerHint);
  246. // ui->widget_title->resize(QApplication::desktop()->screen()->width(), ui->widget_title->height());
  247. // ui->widget_title->move(0,0);
  248. // ui->widget_title->show();
  249. }
  250. void DragAbleWidget::doShowNormal()
  251. {
  252. qDebug()<<__FUNCTION__;
  253. this->show();
  254. this->showNormal();
  255. this->raise();
  256. if (!isMax)
  257. {
  258. ui->widget_frame->setContentsMargins(MARGINS,MARGINS,MARGINS,MARGINS);
  259. showBorderRadius(true);
  260. } else {
  261. ui->widget_frame->setContentsMargins(0,0,0,0);
  262. showBorderRadius(false);
  263. }
  264. ui->btnMenu_Max->setIcon(QIcon(":/image/showmaxsizebtn.png"));
  265. QTimer::singleShot(20,this,[&]()
  266. {
  267. ui->verticalLayout_titleWidget_Back->addWidget(ui->widget_title);
  268. ui->widget_title->show();
  269. });
  270. }
  271. void DragAbleWidget::showBorderRadius(bool isShow)
  272. {
  273. QString str;
  274. if (isShow)
  275. {
  276. str = QString("QWidget#widget_frame\
  277. {\
  278. border:3px solid rgb(46, 165, 255);\
  279. background-color: rgba(255, 255, 255, 0);\
  280. border-radius:5px;\
  281. }\
  282. QWidget#widget_back\
  283. {\
  284. border-radius:3px;\
  285. }\
  286. QWidget#widget_title\
  287. {\
  288. border-top-right-radius:5px;\
  289. border-top-left-radius:5px;\
  290. }\
  291. QWidget#widget_container\
  292. {\
  293. border-bottom-right-radius:5px;\
  294. border-bottom-left-radius:5px;\
  295. }\
  296. QStackedWidget\
  297. {\
  298. border-bottom-right-radius:5px;\
  299. border-bottom-left-radius:5px;\
  300. }\
  301. QWidget#page_courseList\
  302. {\
  303. border-bottom-right-radius:5px;\
  304. border-bottom-left-radius:5px;\
  305. }");
  306. }
  307. else
  308. {
  309. str = QString("QWidget#widget_frame\
  310. {\
  311. border:3px solid rgb(46, 165, 255);\
  312. background-color: rgba(255, 255, 255, 0);\
  313. border-radius:0px;\
  314. }\
  315. QWidget#widget_back\
  316. {\
  317. border-radius:0px;\
  318. }\
  319. QWidget#widget_title\
  320. {\
  321. border-top-right-radius:0px;\
  322. border-top-left-radius:0px;\
  323. }\
  324. QWidget#widget_container\
  325. {\
  326. border-bottom-right-radius:0px;\
  327. border-bottom-left-radius:0px;\
  328. }\
  329. QStackedWidget\
  330. {\
  331. border-bottom-right-radius:0px;\
  332. border-bottom-left-radius:0px;\
  333. }\
  334. QWidget#page_courseList\
  335. {\
  336. border-bottom-right-radius:0px;\
  337. border-bottom-left-radius:0px;\
  338. }");
  339. }
  340. ui->widget_frame->setStyleSheet(str);
  341. }
  342. void DragAbleWidget::doChangeFullScreen()
  343. {
  344. if (this->isFullScreen())
  345. {
  346. this->doShowNormal();
  347. // mAction_FullScreen->setText(tr("show fullscreen"));
  348. }
  349. else
  350. {
  351. this->doShowFullScreen();
  352. // mAction_FullScreen->setText(tr("quit fullscreen"));
  353. }
  354. }
  355. void DragAbleWidget::on_btnMenu_Close_clicked()
  356. {
  357. qDebug()<<__FUNCTION__;
  358. close();
  359. // QTimer::singleShot(500,this,[&]()
  360. // {
  361. // QPoint pt(0, 0);
  362. // QMouseEvent evt(QEvent::Leave, pt, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
  363. // qApp->sendEvent(ui->btnMenu_Close, &evt);
  364. // });
  365. }
  366. void DragAbleWidget::on_btnMenu_Max_clicked()
  367. {
  368. doChangeFullScreen();
  369. }
  370. void DragAbleWidget::on_btnMenu_Min_clicked()
  371. {
  372. if (this->isFullScreen())
  373. {
  374. // mAnimation->stop();
  375. // mTimer_CheckTitle->stop();
  376. ui->widget_title->move(ui->widget_title->x(), 0 - ui->widget_title->height());
  377. ui->widget_title->hide();
  378. }
  379. this->showMinimized();
  380. QTimer::singleShot(500,this,[&]()
  381. {
  382. QPoint pt(0, 0);
  383. QMouseEvent evt(QEvent::Leave, pt, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
  384. qApp->sendEvent(ui->btnMenu_Min, &evt);
  385. });
  386. }
  387. void DragAbleWidget::slotTimerTimeOut()
  388. {
  389. if (QObject::sender() == mTimer)
  390. {
  391. checkCursorDirect(QCursor::pos());
  392. }
  393. }