自定義日曆(三)

1、回顧

    本篇文章以前我想先回顧一下前邊我門所講述的兩篇關於自定義日曆的文章,文章的連接在後續相關連接中均可以看到,第一篇文章中講的是使用QLabel控件拼湊的日曆,好理解,可是性能較第二種方式差,第二種日曆的位置區域和日期文字都是在內存中計算,而後繪製在一個窗口上,性能上確定沒問題。本篇文章依然沿用和自定義日曆(二)同樣使用內容計算位置和日期文字。html

2、效果預覽

    如圖1所示,能夠記錄住當前所選擇的日期的日曆控件,沒有qss美化,比較醜less

圖1 自定義日曆函數

3、實現原理

    看這一節以前,若是有興趣的同窗能夠先下載demo,而後對照着示例代碼看這一小節效果更好。佈局

    首先我先介紹幾個類:post

  • DrawDateTime:日期內容窗口,主要負責繪製當月日期和左右兩個月部分日期
  • CalendarWidget:下拉框預覽窗口,包含了日期頭部和日期內容兩部分
  • DropDataControl:日曆控件類,對外導出類,能夠直接被外部使用。包含當前日期和按鈕,點擊按鈕能夠彈出下拉框

一、DrawDateTime性能

  關於繪製日期內容窗口請參考自定義日曆(二)文章,在此我只簡述一下內容有所改動的地方。ui

  a、添加記錄選中天的數據項,並修改MatchRealDate函數,具體代碼以下:this

 1 //選中天
 2 unsigned short m_wYear;
 3 unsigned short m_wMonth;
 4 unsigned short m_wDay;
 5 
 6 //計算日曆位置
 7 unsigned short m_sYear;
 8 unsigned short m_sMonth;
 9 unsigned short m_sDay;
10 
11 bool MatchRealDate(tDayFlag df)
12 {
13     if (df.m_chFlagD == m_wDay && m_sMonth == m_wMonth)//若是當前月份等於選中月份才認爲是當前選中天
14     {
15         return true;
16     }
17     return false;
18 }

  b、鼠標按下時,更新當前選中天url

 1 void DrawDateTime::mousePressEvent(QMouseEvent * event)
 2 {
 3     if (event->button() == Qt::LeftButton)
 4     {
 5         int cur = GetIndex(event->pos());
 6         if (cur == -1)
 7         {
 8             return;
 9         }
10         tDayFlag & flag = d_ptr->m_aDayFlag[cur];
11 
12         unsigned short year = d_ptr->m_sYear, month = d_ptr->m_sMonth;
13         if (flag.m_chFlagM == -1)
14         {
15             d_ptr->GetPreviousMonth(year, month);
16         }
17         else if (flag.m_chFlagM == 1)
18         {
19             d_ptr->GetNextMonth(year, month);
20         }
21         bool b = (d_ptr->m_wDay != flag.m_chFlagD || month != d_ptr->m_wMonth || year != d_ptr->m_wYear);
22         if (b)
23         {
24             d_ptr->m_wDay = flag.m_chFlagD;
25             d_ptr->m_wMonth = month;
26             d_ptr->m_wYear = year;
27             update();
28         }
29 
30         DataClicked(year, month, d_ptr->m_wDay);//發出信號,用於更新ui界面
31     }
32 }

二、CalendarWidgetspa

  下拉框預覽窗口,包含日期窗口頭,和日期繪製界面。當日期繪製界面發出DataClicked信號時,修改頭部當前年、月,並通知DropDataControl窗口修改日期。按下表頭的上一月和下一月時,修改表頭信息,並通知日期繪製界面修改界面數據,關鍵代碼以下:

 1 d_ptr->m_pDataView = new DrawDateTime;
 2 connect(d_ptr->m_pDataView, &DrawDateTime::DataClicked, this, [this](unsigned short year, unsigned short month, unsigned short day){
 3     emit DataClicked(year, month, day);//通知DropDataControl窗口修改日期
 4     d_ptr->m_pMonth->setText(dataDescribe(year, month));//修改頭部當前年、月
 5 //    setHidden(true);
 6 });
 7 
 8 connect(d_ptr->m_pPrevisou, &QPushButton::clicked, this, [this]{
 9     d_ptr->m_pDataView->PreviousMonth();//並通知日期繪製界面修改界面數據
10     d_ptr->m_pDataView->GetDate(d_ptr->m_wYear, d_ptr->m_wMonth, d_ptr->m_wDay);
11     d_ptr->m_pMonth->setText(dataDescribe(d_ptr->m_wYear, d_ptr->m_wMonth));//修改頭部當前年、月
12 });
13 connect(d_ptr->m_pNext, &QPushButton::clicked, this, [this]{
14     d_ptr->m_pDataView->NextMonth();//並通知日期繪製界面修改界面數據
15     d_ptr->m_pDataView->GetDate(d_ptr->m_wYear, d_ptr->m_wMonth, d_ptr->m_wDay);
16     d_ptr->m_pMonth->setText(dataDescribe(d_ptr->m_wYear, d_ptr->m_wMonth));//修改頭部當前年、月
17 });

三、DropDataControl

  日期空間,對外導出類,能夠被外部直接使用。關於佈局,我就不細說了,貼下關於connect,代碼以下:

 1 connect(d_ptr->m_pDropButton, &QPushButton::clicked, this, &DropDataControl::DropButtonClicked);
 2 connect(d_ptr->m_pDropWidget, &CalendarWidget::DataClicked, this, [this](unsigned short year, unsigned short month, unsigned short day){
 3     d_ptr->m_pText->setText(dataDescribe(year, month, day));//修改QLineEdit文本數據
 4 });
 5 
 6 d_ptr->m_pDropWidget->setWindowFlags(Qt::FramelessWindowHint | Qt::Popup);//彈出式菜單
 7 
 8 void DropDataControl::DropButtonClicked()
 9 {
10     d_ptr->m_pDropWidget->move(mapToGlobal(rect().bottomLeft()));
11     d_ptr->m_pDropWidget->show();
12 }

    上述代碼第6行說明了彈出式窗口是具備Qt::Popup屬性,呵呵,具備這個屬性的窗口都會阻塞主事件循環,也就這個窗口是一個模態框,具體請看圖2關於這個屬性的說明,紅色矩形框中的文字意思就是:這是模態

圖2 Qt::Popup說明

    若是不想要這個窗口是模態的,那麼就不能設置Qt::Popup屬性,具體能夠參見Qt之模擬窗口失去焦點隱藏文章,這篇文章裏簡述了怎麼讓一個窗口失去焦點隱藏的方法,確定不完善,須要本身在根據業務去控制。好了,本篇文章到此就結束了。

4、示例下載

  Qt之自繪製日曆控件(三)

5、相關連接

  自定義日曆(一)

  自定義日曆(二)

  Qt之模擬窗口失去焦點隱藏

若是您以爲文章不錯,不妨給個打賞,寫做不易,感謝各位的支持。您的支持是我最大的動力,謝謝!!! 

 

  


很重要--轉載聲明

  1. 本站文章無特別說明,皆爲原創,版權全部,轉載時請用連接的方式,給出原文出處。同時寫上原做者:朝十晚八 or Twowords
  2. 如要轉載,請原文轉載,如在轉載時修改本文,請事先告知,謝絕在轉載時經過修改本文達到有利於轉載者的目的。 

相關文章
相關標籤/搜索