Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env python
- # -*- coding: utf-8 -*-
- # PyHamClock version 0.2, 12/6/2009
- # PyHamClock displays UTC date and time, along with your local time.
- # Copyright (C) 2009 Martin S. Ewing, AA6E
- #
- # This program is free software: you can redistribute it and/or modify
- # it under the terms of the GNU General Public License as published by
- # the Free Software Foundation, either version 3 of the License, or
- # (at your option) any later version.
- #
- # This program is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU General Public License for more details.
- #
- # You should have received a copy of the GNU General Public License
- # along with this program. If not, see <http://www.gnu.org/licenses/>.
- # Developed with Python 2.6.2 on Ubuntu Linux 9.04. Also tested on Windows XP & 7.
- import wx, sys, time, ConfigParser, os
- BG1 = wx.Colour(0,0,0)
- FG2 = wx.Colour(0,130,0) # dim green
- FG1 = wx.Colour(255, 128, 0) # orange
- INTERVAL = 200 # msec timer period
- # Performance check: On Intel Core 7-920 with INTERVAL=200, CPU load (one thread)
- # is 0.12% over 4 min., after python startup. Atom 230 -> 0.4%
- # We support 3 number size formats, using wxIDs from menu radio buttons.
- F_SMALL = 1000
- F_MEDIUM = 1001
- F_LARGE = 1002
- # These are the actual font sizes to use for each format.
- F_SIZE = { F_SMALL:14, F_MEDIUM:18, F_LARGE:22 }
- # Frame sizes could / should be calculated from the font sizes, but it is
- # easier to wire them in for now...
- FRAME_SIZE = { F_SMALL:(192,50), F_MEDIUM:(234,62), F_LARGE:(282,74) }
- CFG_SECTION = 'pyhamclock'
- CFG_DEFAULTS = { 'hpos': 0, 'vpos': 0, 'format': F_MEDIUM }
- CFG_FILE = 'config.conf'
- # Get human-readable time strings
- def capture():
- time_now = time.time() # use same instant for both conversions
- myformat = "%m/%d %H:%M:%S" # mm/dd HH:MM:SS
- utc_s = time.strftime(myformat, time.gmtime(time_now))
- local_s = time.strftime(myformat, time.localtime(time_now))
- return utc_s, local_s
- # ---- Config. file handler (for window position & size)
- # file name: $HOME/.config/pyhamclock/config.conf
- # File format:
- # [pyhamclock]
- # hpos: nnn # initial frame position (h)
- # vpos: nnn # initial frame position (v)
- # format: n # format (F_SMALL, F_MEDIUM, F_LARGE)
- class PHC_configurator(object):
- def __init__(self):
- cfgdpath = os.path.expanduser('~/.config/pyhamclock')
- if not os.access(cfgdpath, os.W_OK):
- os.makedirs(cfgdpath, 0744) # make dir if needed
- self.cfgpath = os.path.join(cfgdpath,CFG_FILE)
- self.config = ConfigParser.RawConfigParser(CFG_DEFAULTS)
- # Does config.conf file exist & readable? if not, create it with defaults.
- if not os.access(self.cfgpath, os.R_OK):
- self.config.add_section(CFG_SECTION)
- for x in CFG_DEFAULTS:
- self.config.set(CFG_SECTION, x, CFG_DEFAULTS[x])
- with open(self.cfgpath, 'wb') as cfgfile:
- self.config.write(cfgfile)
- else:
- self.config.read(self.cfgpath)
- return None
- def getpos(self):
- hp = self.config.getint(CFG_SECTION, 'hpos')
- vp = self.config.getint(CFG_SECTION, 'vpos')
- return (hp,vp)
- def getformat(self):
- return self.config.getint(CFG_SECTION, 'format')
- def setpos(self, pos):
- self.config.set(CFG_SECTION, 'hpos', pos[0])
- self.config.set(CFG_SECTION, 'vpos', pos[1])
- def setformat(self, fmt):
- self.config.set(CFG_SECTION, 'format', fmt)
- def write(self):
- with open(self.cfgpath, 'wb') as cfgfile:
- self.config.write(cfgfile)
- class MyFrame(wx.Frame):
- def __init__(self, *args, **kwds):
- kwds["style"] = \
- wx.MINIMIZE_BOX|wx.CAPTION|wx.CLOSE_BOX|wx.CLIP_CHILDREN|wx.RESIZE_BORDER
- wx.Frame.__init__(self, *args, **kwds)
- self.menubar = wx.MenuBar()
- self.f_menu = wx.Menu()
- self.f_menu.AppendRadioItem(F_SMALL, "Small")
- self.f_menu.AppendRadioItem(F_MEDIUM, "Medium")
- self.f_menu.AppendRadioItem(F_LARGE, "Large")
- self.f_menu.AppendSeparator()
- quitter = self.f_menu.Append(-1, "Quit", "", wx.ITEM_NORMAL)
- self.menubar.Append(self.f_menu, "File")
- tmp_menu = wx.Menu()
- abouter = tmp_menu.Append(-1, "About", "", wx.ITEM_NORMAL)
- self.menubar.Append(tmp_menu, "Help")
- self.SetMenuBar(self.menubar)
- self.cfg = PHC_configurator() # check $HOME/.config/pyhamclock/config.conf
- posreq = self.cfg.getpos() # position requested by conf file
- scrnsize = wx.GetDisplaySize() # ensure clock is on screen
- posclip = (min(posreq[0], scrnsize[0] - 50),
- min(posreq[1], scrnsize[1] - 50))
- self.SetPosition(posclip)
- # Note that self.format is the wxID of its corresponding menu radio button.
- f = self.cfg.getformat()
- self.format = max(F_SMALL,min(F_LARGE,f))
- # set the corresponding radio button in menu
- for x in F_SIZE:
- self.f_menu.Check(x, self.format == x)
- self.SetTitle("PyHamClock")
- # self.SetToolTipString("PyHamClock!")
- self.Bind(wx.EVT_MENU, self.DoFormat, id=1000, id2=1002)
- self.Bind(wx.EVT_MENU, self.DoQuit, quitter)
- self.Bind(wx.EVT_MENU, self.DoAbout, abouter)
- self.Bind(wx.EVT_CLOSE, self.DoQuit) # (event from close box)
- self.label_utc = wx.StaticText(self, -1, "UTC")
- self.label_utc.SetForegroundColour(FG2)
- self.label_local = wx.StaticText(self, -1, "Local")
- self.label_local.SetForegroundColour(FG2)
- t_utc, t_loc = capture() # Get current times
- self.text_ctrl_utc = wx.StaticText(self,-1, t_utc,
- style=wx.ALIGN_LEFT)
- self.text_ctrl_utc.SetBackgroundColour(BG1)
- self.text_ctrl_utc.SetForegroundColour(FG1)
- self.text_ctrl_local = wx.StaticText(self, -1, t_loc,
- style=wx.ALIGN_LEFT)
- self.text_ctrl_local.SetBackgroundColour(BG1)
- self.text_ctrl_local.SetForegroundColour(FG1)
- self.__do_layout()
- # Set up interval timer
- self.old_time = int(time.time())
- self.timer = wx.Timer(self)
- self.Bind(wx.EVT_TIMER, self.OnTimer, self.timer)
- self.timer.Start(INTERVAL) # continuous
- def __do_layout(self):
- self.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.NORMAL, 0, ""))
- self.SetBackgroundColour(BG1)
- self.SetForegroundColour(FG1)
- time_font = wx.Font(F_SIZE[self.format], wx.SWISS, wx.NORMAL, wx.NORMAL, 0, "")
- self.text_ctrl_utc.SetFont(time_font)
- self.text_ctrl_local.SetFont(time_font)
- self.SetClientSize(FRAME_SIZE[self.format])
- sizer_1 = wx.FlexGridSizer(rows=2, cols=2, hgap=5, vgap=0)
- sizer_1.AddGrowableCol(1)
- sizer_1.Add(self.label_utc, border=4, flag=wx.LEFT|wx.TOP)
- sizer_1.Add(self.text_ctrl_utc)
- sizer_1.Add(self.label_local, border=4, flag=wx.LEFT|wx.TOP)
- sizer_1.Add(self.text_ctrl_local)
- self.SetSizer(sizer_1)
- self.Layout()
- def DoFormat(self, event): # Find which format item is now checked.
- for x in F_SIZE:
- if self.f_menu.IsChecked(x):
- self.format = x # requested format option
- self.__do_layout() # rearrange based on chosen format
- return
- def OnTimer(self, event): # The timer INTERVAL should be <= abt 250 ms
- # to keep well synced with UTC seconds transition.
- int_time = int(time.time()) # int. seconds
- if int_time >= self.old_time + 1: # on most interrupts, nothing happens
- self.old_time = int_time # but we will update display
- utc, loc = capture() # when we pass a 1 sec boundary
- self.text_ctrl_utc.SetLabel(utc)
- self.text_ctrl_local.SetLabel(loc)
- event.Skip()
- event.Skip()
- def DoQuit(self, event):
- # Save our .config info
- self.cfg.setpos(self.GetPosition())
- self.cfg.setformat(self.format)
- self.cfg.write()
- sys.exit()
- def DoAbout(self, event):
- wx.MessageBox(
- """PyHamClock v 0.2
- (c) 2009 Martin Ewing AA6E
- http://aa6e.net, aa6e@arrl.net""")
- event.Skip()
- # end of class MyFrame
- if __name__ == "__main__":
- app = wx.PySimpleApp(0)
- wx.InitAllImageHandlers()
- frame_pyhamclock = MyFrame(None, -1, "")
- app.SetTopWindow(frame_pyhamclock)
- frame_pyhamclock.Show()
- app.MainLoop()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement