Oct-03-2017, 10:21 PM
new to python and wx, I wrote a simple clock program.
It works well for a while but eventually the graphics freeze.
Internally it still runs, but the graphics cease to update.
It unfreezes if I resize the frame and the print buffer releases this error message:
My guess is that the garbage collector loses track of dc.
What did I do wrong?
xClock.py
It works well for a while but eventually the graphics freeze.
Internally it still runs, but the graphics cease to update.
It unfreezes if I resize the frame and the print buffer releases this error message:
Error:GLib-CRITICAL **: Source ID 4759 was not found when attempting to remove it
The id keeps increasing.My guess is that the garbage collector loses track of dc.
What did I do wrong?
xClock.py
# -*- coding: utf-8 -*- # import wx import threading import time from datetime import datetime #return 2 digit string from int def fix(n): s=repr(n) if n<10: s='0'+s return s class xClock(wx.Window): def __init__(self,p): super(xClock, self).__init__(p) self.W=400 self.H=100 self.SetSize(wx.Size(self.W,self.H)) self.R=195 self.img=None self.DRAWN=False self.timeText="" self.SetForegroundColour(wx.BLUE) self.font=self.GetFont() w,h,d,e =self.GetFullTextExtent('00:00:00') FE=[w,h,d,e] print ('GetFullTextExtent '+ repr(FE)) self.font.SetPointSize(70) self.SetFont(self.font) w,h,d,e =self.GetFullTextExtent('00:00:00') FE=[w,h,d,e] print ('GetFullTextExtent '+ repr(FE)) wx.EVT_PAINT(self,self.OnPaint) wx.EVT_WINDOW_DESTROY=self.stop() self.RUNNING=False self.ticker=None self.start() def OnPaint(self, evt): if self.img==None: self.draw() return False dc=wx.PaintDC(self) dc.BeginDrawing() w,h=self.img.GetSize() W,H=self.GetSize() x=(W-w)//2 y=(H-h)//2 dc.DrawBitmap(self.img,x,y) dc.EndDrawing() return True def draw(self): if self.img==None: self.img=wx.EmptyBitmap(self.W,self.H) self.DRAWN=False now=datetime.now() h=fix(now.hour) m=fix(now.minute) s=fix(now.second) t=h+":"+m+":"+s self.timeText=t dc = wx.MemoryDC() dc.SelectObject(self.img) dc.BeginDrawing() F=self.GetFont() dc.SetFont(F) w,h=dc.GetTextExtent(t) W,H=self.img.GetSize() x0=(self.W-w)//2 y0=(self.H-h)//2 dc.SetBrush(wx.Brush(wx.WHITE, wx.SOLID)) dc.Clear() dc.SetTextForeground(wx.BLUE) dc.DrawText(t,x0,y0) self.DRAWN=True dc.EndDrawing() self.Refresh() def start(self): pass if self.ticker ==None or not self.ticker.is_alive(): self.ticker=threading.Thread(None, self.run, "Ticker") print("start() "+self.ticker.getName()) self.ticker.start() def stop(self): self.RUNNING=False time.sleep(2) def run(self): self.RUNNING=True delay=1 print("RUNNING") while self.RUNNING: self.draw() self.Refresh(False) time.sleep(delay) #T=threading.currentThread().getName() # just curious # print(self.timeText+' '), # prove it runs when frozen print(self.timeText) self.RUNNING=False__init__.py
#!/usr/bin/python # -*- coding: utf-8 -*- import wx from xClock import xClock class XCFrame(wx.Frame): def __init__(self,parent): super(XCFrame, self).__init__(parent) self.SetTitle("XAOS CLOCK") xcp=xClock(self) sizer=wx.BoxSizer(wx.VERTICAL) sizer.Add(xcp,1,wx.EXPAND,wx.ALL) self.SetBackgroundColour(wx.CYAN) self.SetSizer(sizer) class xaosApp(wx.App): def __init__(self): super(xaosApp, self).__init__() xcf=XCFrame(None) xcf.Show() if __name__=='__main__': app=xaosApp() app.MainLoop()