首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 更多程式設計知識

wxPython wx.Timer 定時器實戰教學:打造即時時鐘 GUI 程式

     編輯:更多程式設計知識

在 GUI 應用程式中,定時更新介面元素是常見需求——例如即時時鐘、進度條輪詢、動畫幀更新等。wxPython 提供 wx.Timer 類別,讓開發者能以事件驅動方式輕鬆實作週期性任務。本文將透過一個完整的「即時時鐘」範例,詳細說明 wx.Timer 的建立、綁定、啟動與停止流程。

核心概念速覽

方法/事件用途
wx.Timer(owner)建立定時器,指定事件接收者
Bind(wx.EVT_TIMER, handler, timer)將定時器事件綁定至處理函式
timer.Start(interval, oneShot=False)啟動定時器,interval 以毫秒為單位
timer.Stop()停止定時器
wx.EVT_TIMER定時器觸發事件

完整範例程式碼

# -*- coding: utf-8 -*-
import wx
import time

class MyFrame(wx.Frame):
    def __init__(self, parent):
        super().__init__(parent, id=wx.ID_ANY, title="即時時鐘示範",
                         pos=wx.DefaultPosition, size=wx.Size(483, 155),
                         style=wx.DEFAULT_FRAME_STYLE | wx.TAB_TRAVERSAL)

        self.SetBackgroundColour(wx.SystemSettings.GetColour(wx.SYS_COLOUR_INACTIVECAPTIONTEXT))

        # 版面配置:兩顆按鈕並排
        gSizer = wx.GridSizer(0, 2, 0, 0)
        self.btn_start = wx.Button(self, wx.ID_ANY, "啟動定時器")
        self.btn_stop = wx.Button(self, wx.ID_ANY, "停止定時器")
        gSizer.Add(self.btn_start, 0, wx.ALL, 5)
        gSizer.Add(self.btn_stop, 0, wx.ALL, 5)
        self.SetSizer(gSizer)
        self.Layout()

        # 狀態列:兩欄分別顯示日期與時間
        self.status_bar = self.CreateStatusBar(2, wx.ST_SIZEGRIP)
        self.Centre(wx.BOTH)

        # 事件綁定
        self.btn_start.Bind(wx.EVT_BUTTON, self.on_start)
        self.btn_stop.Bind(wx.EVT_BUTTON, self.on_stop)

        # 建立並綁定定時器
        self.timer = wx.Timer(self)
        self.Bind(wx.EVT_TIMER, self.on_timer, self.timer)

    def on_start(self, event):
        """啟動定時器,間隔 1000 ms(1 秒)"""
        self.timer.Start(1000)

    def on_stop(self, event):
        """停止定時器"""
        self.timer.Stop()

    def on_timer(self, event):
        """定時器觸發:更新狀態列日期與時間"""
        t = time.localtime()
        date_str = time.strftime("%Y-%B-%d", t)      # 例:2025-January-15
        time_str = time.strftime("%I:%M:%S", t)      # 例:03:45:20
        self.SetStatusText(date_str, 0)
        self.SetStatusText(time_str, 1)

    def __del__(self):
        pass

if __name__ == '__main__':
    app = wx.App()  # wx.PySimpleApp() 在新版已棄用
    frame = MyFrame(None)
    frame.Show()
    app.MainLoop()

關鍵步驟解析

1. 建立定時器與綁定事件

self.timer = wx.Timer(self)                    # self 為事件接收者
self.Bind(wx.EVT_TIMER, self.on_timer, self.timer)  # 指定處理函式

採用 Bind 而非舊式 EVT_TIMER 巨集,符合現代 wxPython 風格,且支援多定時器共存。

2. 啟動與間隔設定

self.timer.Start(1000)  # 每 1000 ms 觸發一次

若需單次觸發,可傳入 oneShot=True。

3. 事件處理函式更新 UI

def on_timer(self, event):
    t = time.localtime()
    self.SetStatusText(time.strftime("%Y-%B-%d", t), 0)
    self.SetStatusText(time.strftime("%I:%M:%S", t), 1)

在事件處理函式中直接操作 UI 元件是安全的,因為 wxPython 事件迴圈運行於主執行緒。

執行畫面

wxPython Timer 即時時鐘執行畫面

進階應用提示

  • 多定時器管理:建立多個 wx.Timer 實例,分別綁定不同處理函式,互不干擾。
  • 高精度需求:wx.Timer 精度約 10-15 ms,若需微秒級定時,請改用 threading.Timer 或 asyncio 搭配 wx.CallAfter 回主執行緒更新 UI。
  • 資源釋放:視窗關閉前呼叫 timer.Stop(),避免殘留事件導致例外。

常見錯誤與除錯

現象可能原因解決方案
定時器不觸發未呼叫 Start() 或間隔設為 0確認 Start(interval>0)
UI 凍結在 on_timer 執行耗時運算將耗時工作移至背景執行緒,用 wx.CallAfter 更新 UI
重複觸發多次呼叫 Start() 未先 Stop()啟動前先檢查 timer.IsRunning()
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved