Python--物件導向程式設計--時鐘例項開發

Kobe10發表於2016-07-27
  • 在學習python物件導向程式設計的時候,心血來潮,決定寫一個時鐘模型來玩玩,所以就有了現在這個小玩意,不過python這個東西確實是挺好玩的
  • 方法;運用python的tkinter庫開發圖形化時鐘程式
    •   時鐘啟動時以系統的時間為當前的時間
    •   時鐘有時針、分針和秒針
    •   錶盤可以切換為程式繪製的或基於圖片的樣式

  • 物件分析
    •   指標:
      • 座標集(針頭座標和針頭座標)
      • 當前位置座標(繪製各種針的當前位置)
      • 顏色,粗細,當前指標的圖形ID(把前一個id刪除),畫布物件
      • 當前指標的上級指標,上下級指標的行走關係(分針走一格,秒針走多少格),行走一格,
      • 設定起始位置,繪製指標,刪除指標
    •   基本錶盤
      • 所有刻度線起訖點座標(繪製每一個刻度線)
      • 畫布引用
      • 繪製刻度線,刪除刻度線
    •   影象錶盤
      • 刻度圖
        • 影象名稱
        • 繪製id,繪製刪除指定影象檔案
      • 裝飾圖
        • 影象名稱
        • 繪製ID,刪除繪製指定影象檔案
    • 鐘錶
      • 三種型別的指標
      • 錶盤
      • 切換錶盤的按鈕
      • 設定圖形錶盤影象
      • 切換錶盤(按鈕)


  • d程式碼實現
    •   
        1 #coding=gbk
        2 # -*- encoding:utf-8 -*-
        3 
        4 import time,datetime
        5 import math
        6 import itertools
        7 import tkinter
        8 import threading
        9 
       10 def get_clock_step(base_pntr,long_pntr):
       11     pos = []
       12     for i in range(60):
       13         pos.append((base_pntr[0]+long_pntr*math.cos(i*math.pi/30),
       14             base_pntr[0]+long_pntr*math.sin(i*math.pi/30)))
       15     return pos[45:] + pos[:45]
       16 
       17 def gen_i_pos(c_pntr,long_pntr):
       18     for i,p in enumerate(get_clock_step(c_pntr,long_pntr)):
       19         yield i,p
       20 
       21 class Pointer:
       22 
       23     def __init__(self,c_pntr,long_pntr,cvns,scale=None,super_pntr=None,width=1,fill='black'):
       24         # 引數說明:
       25         # c_pntr: 錶盤的中心座標;
       26         # long_pntr: 錶針長;
       27         # cvns: 畫布引用;
       28         # scale: 指標行走比例;
       29         # super_pntr: 上級指標;
       30         # width: 指標粗細;
       31         # fill: 指標顏色;
       32         self.pos_iter = itertools.cycle(gen_i_pos(c_pntr,long_pntr))
       33         self.scale = scale
       34         self.cvns = cvns
       35         self.crrnt_pos = self.pos_iter.__next__()[1]
       36         self.c_pntr = c_pntr
       37         self.super_pntr = super_pntr
       38         self.id_pntr = None
       39         self.width = width
       40         self.fill = fill
       41 
       42     def draw(self):
       43         self.id_pntr = cvns.create_line(self.c_pntr,self.crrnt_pos,width=self.width,fill=self.fill)
       44 
       45     def walk_step(self):
       46         self.delete()
       47         self.draw()
       48         i,self.crrnt_pos = self.pos_iter.__next__()
       49         if self.super_pntr and self.scale and (i + 1) % self.scale == 0:
       50             self.super_pntr.walk_step()
       51 
       52     def delete(self):
       53         if self.id_pntr:
       54             self.cvns.delete(self.id_pntr)
       55 
       56     def set_start(self,steps):
       57         for i in range(steps-1):
       58             self.pos_iter.__next__()
       59         self.crrnt_pos = self.pos_iter.__next__()[1]
       60 
       61 class PlateImg:
       62 
       63     def __init__(self,c_pntr,clock_r,cvns,img):
       64         self.cvns = cvns
       65         self.clock_r = clock_r
       66         self.c_pntr = c_pntr
       67         self.img = img
       68         self.pid = None
       69         self.draw()
       70 
       71     def draw(self):
       72         self.im = tkinter.PhotoImage(file=self.img)
       73         self.pid = self.cvns.create_image(self.c_pntr,image = self.im)
       74 
       75     def delete(self):
       76         if self.pid:
       77             self.cvns.delete(self.pid)
       78 
       79     def set_img(self,img):
       80         self.img = img
       81         self.delete()
       82         self.draw()
       83 
       84 
       85 
       86 class InImg(PlateImg):
       87     def draw(self):
       88         x = self.c_pntr[0]
       89         y = self.c_pntr[0] + self.clock_r / 5
       90         self.im = tkinter.PhotoImage(file=self.img)
       91         self.pid = self.cvns.create_image(x,y,image = self.im)
       92 
       93 class CustomPlate:
       94     def __init__(self,c_pntr,clock_r,cvns,imgp='platex.gif',imgi='flowersx.gif'):
       95         self.pi = PlateImg(c_pntr,clock_r,cvns,imgp)
       96         self.ii = InImg(c_pntr,clock_r,cvns,imgi)
       97 
       98     def set_img(self,imgp,imgi):
       99         self.pi.set_img(imgp)
      100         self.ii.set_img(imgi)
      101 
      102     def delete(self):
      103         self.pi.delete()
      104         self.ii.delete()
      105 
      106 
      107 class Plate:
      108     
      109     def __init__(self,c_pntr,clock_r,cvns,long=10):
      110         self.pos_a = get_clock_step(c_pntr,clock_r - long)
      111         self.pos_b = get_clock_step(c_pntr,clock_r)
      112         self.cvns = cvns
      113         self.plates = []
      114         self.draw()
      115 
      116     def draw(self):
      117         for i,p in enumerate(zip(self.pos_a,self.pos_b)):
      118             width = 5 if (i + 1) % 5 == 0 else 3
      119             pid = self.cvns.create_line(*p,width=width)
      120             self.plates.append(pid)
      121 
      122     def delete(self):
      123         if self.plates:
      124             for item in self.plates:
      125                 self.cvns.delete(item)
      126 
      127 class MyClock:
      128 
      129     def __init__(self,base_pntr,clock_r,cvns):
      130         self.c_pntr = base_pntr
      131         self.clock_r = clock_r
      132         self.cvns = cvns
      133         self.plate = Plate(base_pntr,clock_r,self.cvns)
      134         h,m,s = self.start_time()
      135         self.h_pntr = Pointer(base_pntr,3 * clock_r // 5,self.cvns,width=5,fill='blue')
      136         self.m_pntr = Pointer(base_pntr,4 * clock_r // 5,self.cvns,12,super_pntr=self.h_pntr,width=3,fill='green')
      137         self.h_pntr.set_start(h * 5)
      138         self.m_pntr.set_start(m)
      139         self.h_pntr.walk_step()
      140         self.m_pntr.walk_step()
      141         self.s_pntr = Pointer(base_pntr,clock_r-5,self.cvns,60,super_pntr=self.m_pntr,fill='red')
      142         self.s_pntr.set_start(s)
      143 
      144     def chg_plate(self):
      145         self.plate.delete()
      146         if isinstance(self.plate,CustomPlate):
      147             self.plate = Plate(self.c_pntr,self.clock_r,self.cvns)
      148         else:
      149             self.plate = CustomPlate(self.c_pntr,self.clock_r,self.cvns)
      150         self.h_pntr.delete()
      151         self.h_pntr.draw()
      152         self.m_pntr.delete()
      153         self.m_pntr.draw()
      154 
      155     def set_img(self,imgp,imgi):
      156         if not isinstance(self.plate,CustomPlate):
      157             self.chg_plate()
      158         self.plate.set_img(imgp,imgi)
      159 
      160     def walk_step(self):
      161         self.s_pntr.walk_step()
      162 
      163     def start_time(self):
      164         crrnt_time = datetime.datetime.now()
      165         hour = crrnt_time.hour
      166         minute = crrnt_time.minute
      167         second = crrnt_time.second
      168         return hour,minute,second
      169 
      170 class MyButton:
      171     def __init__(self,root,clock):
      172         self.clock = clock
      173         button = tkinter.Button(root,text = '改變錶盤',command = self.chg_plate)
      174         button.pack()
      175 
      176     def chg_plate(self):
      177         self.clock.chg_plate()
      178 
      179 class MyTk(tkinter.Tk):
      180     def quit(self):
      181         StartClock.looping = False
      182         self.quit()
      183 
      184 class StartClock:
      185     looping = True
      186     def __init__(self,mc,root):
      187         self.mc = mc
      188         self.root = root
      189 
      190     def start_clock(self):
      191         while StartClock.looping:
      192             self.mc.walk_step()
      193             self.root.update()
      194             time.sleep(0.05)
      195 
      196 if __name__ == '__main__':
      197     root = MyTk()
      198     cvns = tkinter.Canvas(root,width=400,height=400,bg='white')
      199     cvns.pack()
      200     mc = MyClock((200,200),200,cvns)
      201     bt = MyButton(root,mc)
      202     t = threading.Thread(target=StartClock(mc,root).start_clock)
      203     t.setDaemon(True)
      204     t.start()
      205     root.resizable(False, False)
      206     root.mainloop()

       

    • 剛剛學習,謝謝指出錯誤!

相關文章