📄 analogclock.py
字号:
# AnalogClock's main class
# E. A. Tacao <e.a.tacao |at| estadao.com.br>
# http://j.domaindlx.com/elements28/wxpython/
# 15 Fev 2006, 22:00 GMT-03:00
# Distributed under the wxWidgets license.
#
# For more info please see the __init__.py file.
import wx
from styles import *
from helpers import Dyer, Face, Hand, HandSet, TickSet, Box
from setup import Setup
#----------------------------------------------------------------------
class AnalogClock(wx.PyWindow):
"""An analog clock."""
def __init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition,
size=wx.DefaultSize, style=wx.NO_BORDER, name="AnalogClock",
clockStyle=DEFAULT_CLOCK_STYLE,
minutesStyle=TICKS_CIRCLE, hoursStyle=TICKS_POLY):
wx.PyWindow.__init__(self, parent, id, pos, size, style, name)
# Base size for scale calc purposes.
self.basesize = wx.Size(348, 348)
# Store some references.
self.clockStyle = clockStyle
self.minutesStyle = minutesStyle
self.hoursStyle = hoursStyle
self.DrawHands = self._drawHands
self.DrawBox = self._drawBox
self.RecalcCoords = self._recalcCoords
self.shadowOffset = 3
self.allHandStyles = [SHOW_HOURS_HAND,
SHOW_MINUTES_HAND,
SHOW_SECONDS_HAND]
# Initialize clock face.
#
# By default we don't use colours or borders on the clock face.
bg = self.GetBackgroundColour()
face = Face(dyer=Dyer(bg, 0, bg))
# Initialize tick marks.
#
# TickSet is a set of tick marks; there's always two TickSets defined
# regardless whether they're being shown or not.
ticksM = TickSet(self, style=minutesStyle, size=5, kind="minutes")
ticksH = TickSet(self, style=hoursStyle, size=25, kind="hours",
rotate=clockStyle&ROTATE_TICKS)
# Box holds the clock face and tick marks.
self.Box = Box(self, face, ticksM, ticksH)
# Initialize hands.
#
# HandSet is the set of hands; there's always one HandSet defined
# regardless whether hands are being shown or not.
#
# A 'lenfac = 0.95', e.g., means that the lenght of that hand will
# be 95% of the maximum allowed hand lenght ('nice' maximum lenght).
handH = Hand(size=7, lenfac=0.7)
handM = Hand(size=5, lenfac=0.95)
handS = Hand(size=1, lenfac=0.95)
self.Hands = HandSet(self, handH, handM, handS)
# Create the customization dialog.
self.Setup = None
# Make a context menu.
popup1 = wx.NewId()
popup2 = wx.NewId()
cm = self.cm = wx.Menu()
cm.Append(popup1, "Customize...")
cm.Append(popup2, "About...")
# Set event handlers.
self.Bind(wx.EVT_SIZE, self._OnSize)
self.Bind(wx.EVT_PAINT, self._OnPaint)
self.Bind(wx.EVT_ERASE_BACKGROUND, lambda evt: None)
self.Bind(wx.EVT_TIMER, self._OnTimer)
self.Bind(wx.EVT_WINDOW_DESTROY, self._OnDestroyWindow)
self.Bind(wx.EVT_CONTEXT_MENU, self._OnContextMenu)
self.Bind(wx.EVT_MENU, self._OnShowSetup, id=popup1)
self.Bind(wx.EVT_MENU, self._OnShowAbout, id=popup2)
# Set initial size based on given size, or best size
self.SetBestFittingSize(size)
# Do initial drawing (in case there is not an initial size event)
self.RecalcCoords(self.GetSize())
self.DrawBox()
# Initialize the timer that drives the update of the clock face.
# Update every half second to ensure that there is at least one true
# update during each realtime second.
self.timer = wx.Timer(self)
self.timer.Start(500)
def DoGetBestSize(self):
# Just pull a number out of the air. If there is a way to
# calculate this then it should be done...
size = wx.Size(50,50)
self.CacheBestSize(size)
return size
def _OnSize(self, evt):
size = self.GetClientSize()
if size.x < 1 or size.y < 1:
return
self.RecalcCoords(size)
self.DrawBox()
def _OnPaint(self, evt):
dc = wx.BufferedPaintDC(self)
self.DrawHands(dc)
def _OnTimer(self, evt):
dc = wx.BufferedDC(wx.ClientDC(self), self.GetClientSize())
self.DrawHands(dc)
def _OnDestroyWindow(self, evt):
self.timer.Stop()
del self.timer
def _OnContextMenu(self, evt):
self.PopupMenu(self.cm)
def _OnShowSetup(self, evt):
if self.Setup is None:
self.Setup = Setup(self)
self.Setup.Show()
self.Setup.Raise()
def _OnShowAbout(self, evt):
msg = "AnalogClock\n\n" \
"by Several folks on wxPython-users\n" \
"with enhancements from E. A. Tacao."
title = "About..."
style = wx.OK|wx.ICON_INFORMATION
dlg = wx.MessageDialog(self, msg, title, style)
dlg.ShowModal()
dlg.Destroy()
def _recalcCoords(self, size):
"""
Recalculates all coordinates/geometry and inits the faceBitmap
to make sure the buffer is always the same size as the window.
"""
self.faceBitmap = wx.EmptyBitmap(*size.Get())
# Recalc all coords.
scale = min([float(size.width) / self.basesize.width,
float(size.height) / self.basesize.height])
centre = wx.Point(size.width / 2., size.height / 2.)
self.Box.RecalcCoords(size, centre, scale)
self.Hands.RecalcCoords(size, centre, scale)
# Try to find a 'nice' maximum length for the hands so that they won't
# overlap the tick marks. OTOH, if you do want to allow overlapping the
# lenfac value (defined on __init__ above) has to be set to
# something > 1.
niceradius = self.Box.GetNiceRadiusForHands(centre)
self.Hands.SetMaxRadius(niceradius)
def _drawBox(self):
"""Draws clock face and tick marks."""
dc = wx.BufferedDC(wx.ClientDC(self), self.GetClientSize())
dc.BeginDrawing()
dc.SelectObject(self.faceBitmap)
dc.SetBackground(wx.Brush(self.GetBackgroundColour(), wx.SOLID))
dc.Clear()
self.Box.Draw(dc)
dc.EndDrawing()
def _drawHands(self, dc):
"""
Draws the face bitmap, created on the last DrawBox call, and
clock hands.
"""
dc.BeginDrawing()
dc.DrawBitmap(self.faceBitmap, 0, 0)
self.Hands.Draw(dc)
dc.EndDrawing()
# Public methods --------------------------------------------------
def GetHandSize(self, target=ALL):
"""Gets thickness of hands."""
return self.Hands.GetSize(target)
def GetHandFillColour(self, target=ALL):
"""Gets fill colours of hands."""
return self.Hands.GetFillColour(target)
def GetHandBorderColour(self, target=ALL):
"""Gets border colours of hands."""
return self.Hands.GetBorderColour(target)
def GetHandBorderWidth(self, target=ALL):
"""Gets border widths of hands."""
return self.Hands.GetBorderWidth(target)
def GetTickSize(self, target=ALL):
"""Gets sizes of ticks."""
return self.Box.GetTickSize(target)
def GetTickFillColour(self, target=ALL):
"""Gets fill colours of ticks."""
return self.Box.GetTickFillColour(target)
def GetTickBorderColour(self, target=ALL):
"""Gets border colours of ticks."""
return self.Box.GetTickBorderColour(target)
def GetTickBorderWidth(self, target=ALL):
"""Gets border widths of ticks."""
return self.Box.GetTickBorderWidth(target)
def GetTickPolygon(self, target=ALL):
"""
Gets lists of points to be used as polygon shapes
when using the TICKS_POLY style.
"""
return self.Box.GetTickPolygon(target)
def GetTickFont(self, target=ALL):
"""
Gets fonts for tick marks when using TICKS_DECIMAL or
TICKS_ROMAN style.
"""
return self.Box.GetTickFont(target)
def GetTickOffset(self, target=ALL):
"""Gets the distance of tick marks for hours from border."""
return self.Box.GetTickOffset(target)
def GetFaceFillColour(self):
"""Gets fill colours of watch."""
return self.Box.Face.GetFillColour()
def GetFaceBorderColour(self):
"""Gets border colours of watch."""
return self.Box.Face.GetBorderColour()
def GetFaceBorderWidth(self):
"""Gets border width of watch."""
return self.Box.Face.GetBorderWidth()
def GetShadowColour(self):
"""Gets the colour to be used to draw shadows."""
a_clock_part = self.Box
return a_clock_part.GetShadowColour()
def GetClockStyle(self):
"""Returns the current clock style."""
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -