cdate.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. #include "cdate.h"
  2. #include <QHBoxLayout>
  3. #include <QPainter>
  4. #include <QEvent>
  5. #include <QDebug>
  6. #include <QMouseEvent>
  7. #include <QEventLoop>
  8. #include "calendarwidgetex.h"
  9. #include "oneshadow.h"
  10. CDate::CDate(const QDate& defaultDate,QWidget *parent,PopupType type) :
  11. QWidget{parent},
  12. m_parent(parent),
  13. m_type(type)
  14. {
  15. init(defaultDate);
  16. }
  17. CDate::CDate(QWidget *parent,PopupType type) :
  18. QWidget{parent},
  19. m_parent(parent),
  20. m_type(type)
  21. {
  22. // if(type == Popup)
  23. // {
  24. // setWindowFlags(Qt::FramelessWindowHint | Qt::Popup);
  25. // }
  26. init(QDate::currentDate());
  27. }
  28. /* 阻塞执行 */
  29. QDate CDate::execShow()
  30. {
  31. this->show();
  32. QEventLoop loop;
  33. connect(this, &CDate::signal_close, &loop, &QEventLoop::quit);
  34. loop.exec();
  35. return m_date;
  36. }
  37. /* 设置日期 */
  38. void CDate::setDate(const QDate& date)
  39. {
  40. m_date = date;
  41. m_calendarEx->setSelectedDate(date);
  42. }
  43. void CDate::paintEvent(QPaintEvent *event)
  44. {
  45. QPainter painter(this);
  46. painter.setRenderHint(QPainter::Antialiasing);
  47. painter.drawImage(QPoint(0,0),m_shadow->image());
  48. }
  49. /**
  50. * @brief 在这里实现点击空白处隐藏或者关闭自身
  51. * @param watched
  52. * @param event
  53. * @return
  54. */
  55. bool CDate::eventFilter(QObject *watched, QEvent *event)
  56. {
  57. auto me = dynamic_cast<QMouseEvent*>(event);
  58. if(nullptr != me)
  59. {
  60. if(me->type() == QEvent::MouseButtonPress)
  61. {
  62. if(m_type == Popup)
  63. {
  64. /* 先将自身区域和鼠标坐标都转换成全局坐标 */
  65. QPoint gTopLeft = this->mapToGlobal(this->rect().topLeft());
  66. QRect gRect(gTopLeft.x(),gTopLeft.y(),this->width(),this->height());
  67. /* 判断此时的鼠标坐标是否在这个控件中 */
  68. if(!gRect.contains(me->globalPos()))
  69. {
  70. // qDebug() << QTime::currentTime() << "CDate关闭了";
  71. emit signal_DateChanged(m_date);
  72. /* 发送信号,关闭自身 */
  73. emit signal_close();
  74. this->close();
  75. }
  76. }
  77. }
  78. }
  79. return QWidget::eventFilter(watched,event);
  80. }
  81. void CDate::init(const QDate &defaultDate)
  82. {
  83. /* 设置无边框 */
  84. setWindowFlags(Qt::FramelessWindowHint);
  85. /* 设置底层样式表,让最底层的透明 */
  86. this->setAttribute(Qt::WA_TranslucentBackground);
  87. /* 将父类的事件注册给自己 */
  88. if(m_type == Popup && m_parent != nullptr)
  89. {
  90. m_parent->installEventFilter(this);
  91. }
  92. /* 设置布局,通过设置layout的Margin距离显示阴影 */
  93. QHBoxLayout* layout = new QHBoxLayout(this);
  94. this->setLayout(layout);
  95. layout->setMargin(RADIUS);
  96. this->resize(CALENDAR_WIDTH + RADIUS*2,CALENDAR_HEIGHT + RADIUS*2);
  97. /* 设置日历组件 */
  98. m_calendarEx = new CalendarWidgetEx(this);
  99. m_calendarEx->resize(CALENDAR_WIDTH,CALENDAR_HEIGHT);
  100. m_calendarEx->setCurrentPage(defaultDate.year(),defaultDate.month());
  101. m_calendarEx->setSelectedDate(defaultDate);
  102. layout->addWidget(m_calendarEx);
  103. /* 设置自身时间 */
  104. m_date = defaultDate;
  105. /* 设置阴影 */
  106. m_shadow = new OneShadow(QSize(m_calendarEx->width(),m_calendarEx->height()),RADIUS);
  107. /* 信号和槽 */
  108. connect(m_calendarEx,&CalendarWidgetEx::clicked,this,[this](const QDate& date){
  109. m_date = date;
  110. emit signal_DateChanged(date);
  111. emit signal_close();
  112. this->close();
  113. });
  114. }