#PYTHON3 #QT #PYSISE2 #TUTORIAL #QTIMER #QCALENDAR #QDATEEDIT

PySide #16: 時間的重要性(上), QTimer, QCalendar, QDateEdit

一起成為時間管理大師!

DekBan
Bucketing

--

Photo by Aron Visuals on Unsplash

時間是非常管理是非常重要的,想要成為時間管理大師就要對各個計時器瞭若指掌,同時也要用有效的方式來顯示時間,讓使用者可以清楚的了解時間的概況。
雖然本篇篇幅比較短,但計時器的使用實際上是非常常用到的,尤其是在做routine job的時候,同時Qt中的QTimer計時器可以製造一種多執行緒的錯覺,但實際上不是唷!詳細可以看這裏

🕕 QTimer

QTimer是個計時器,讓開發者可以定期執行想要的工作task,很類似寫firmware中遇到的輪巡的感覺,使用上也非常簡單,主要是串接timer的 timeout()訊號槽以及要執行的function,最後利用 start(msec)函式來定期執行我們要的function。

implement

# In __init__()
self._counter = 100
self._count_timer = QTimer(self._window)
self._count_timer.timeout.connect(self.count_down)
self._count_timer.start(1000)

@QtCore.Slot()
def count_down(self):
self._counter -= 1
print(self._counter)
QTimer Demo

這時候你會說,但他停不下來啊!?
沒錯,所以我們要設定中斷條件,並且在為了更加嚴謹我們會在開始start以前以及結束前都利用 isActive()函式來確認目前Timer的狀態,最後用 stop()來停止Timer。

if not self._count_timer.isActive():
self._count_timer.start(1000)
@QtCore.Slot()
def count_down(self):
self._counter -= 1
print(self._counter)

if self._counter is 95 and self._count_timer.isActive():
self._count_timer.stop()

Timer可以同時有多個存在於程式中,但要注意一點,因為Timer其實更像是輪循中的flag當被觸發時就執行函式,執行完才繼續向下跑,因此如果每個Timer所連接的Slot函式執行太長的時間,就會造成有點delay的現象。

如果真的要精準且獨立的計時並同時處理不同的task,還是用QThread或是利用python的threading來執行會更加合適,事實上,在python中我通常會理用python的threading來處理非同步事件,寫起來方便有不用依賴Qt Library

📅 QDateEdit

QDateEdit是個非常簡單的物件,能讓使用者選取日期並輸出QDate的日期物件,包含年月日等等參數,跟Python中的DateTime模組基本上是大同小異的。

Declare

我們一樣是從QtDesigner中拉取,並設定其各個參數。

def set_date_edit(self):
date_edit = self._window.date_edit
date_edit.setDisplayFormat('yyyy-MM-dd')

另外我們也可以將等等要介紹的QCalendar加入QDateEdit中,達到彈跳視窗的效果。

# This will make calendar as a pop window
date_edit.setCalendarPopup(True)
date_edit.setCalendarWidget(self._window.calendar)
QDateEdit demo

🗓️ QCalendar

選取日期以及顯示日期的功能在應用程式中非常常見且實用,除了用QLineEdit等物件一個一個的刻,我們也能使用Qt內建的QCalendar來做選取日期以及顯示,外觀上更加直覺也更方便使用。

Outlook

外觀顯示上,QCalendar有三組enum值用來定義日曆的顯示細節,其分別為:水平Header顯示、垂直Header顯示、選取模式。

詳細內容如下:

  • 水平表頭:主要以不同方式顯示星期的方式
  • 垂直表頭:決定是否顯示週數
  • 選取模式:分為可選取跟不可選取(等於純顯示用)
https://doc.qt.io/qt-5/qcalendarwidget.html#HorizontalHeaderFormat-enum

除此之外,還有許多厲害的外觀功能可以設定,在開始以下範例之前,我們要先從QtDesigner中拉入QCalendarWidget物件,然後開始在程式中設定。

def set_calendar(self):
"""Setup Calendar widget"""
calendar = self._window.calendar

隔線顯示

    calendar.setGridVisible(True)

星期Style

# 設定第一天為星期幾
calendar.setFirstDayOfWeek(Qt.Thursday)
# 設定各星期該日的顏色 (此處將週末設為綠色)
from PySide2.QtGui import QBrush, QTextCharFormat
weekend_format = QTextCharFormat()
weekend_format.setForeground(QBrush(Qt.green, Qt.SolidPattern))
calendar.setWeekdayTextFormat(Qt.Saturday, weekend_format)
calendar.setWeekdayTextFormat(Qt.Sunday, weekend_format)

特殊日Style

# 將某個特定日期設為不同顏色 用於特殊日顯示
calendar.setDateTextFormat(QDate(2020, 9, 9), weekend_format)
QCalendar display demo

Feature

當然外觀很炫炮,功能還是要有QCalendar主要有幾個常見的Signal提供給開發者,包括 clickedselectionChangedcurrentPageChanged…等等。

另外,通常我們的日曆都會有上下限的設定,用以避免不合法的日期出現。

calendar.setMinimumDate(QDate(1900, 1, 1))
calendar.setMaximumDate(QDate.currentDate())

串接Signal、Slot

calendar.clicked.connect(self._window.date_edit.setDate)
QCalendar signal / slot

Source Code

完整代碼請看 :timer_calendar

結論

QCalendar跟QDateEdit經常一起使用,可以看得出來兩個物件上是有高度相依且可以串連的,日期的部分基本上都可以被這兩個物件給Cover掉,同時要注意QDate等輔助用的物件的用法,下一章會介紹時間的物件,讓我們繼續朝時間管理大師邁進吧!

我是夜海中的宅男DekBan,我們下次見,see ya next night.

Next Step: PySide #17: 時間的重要性(下), QTimeEdit, QLCDNumber, AnalogClock

--

--

DekBan
Bucketing

เด็กบ้าน | 🌃夜裡溜搭的宅男,漂泊於月色鋪成的海