I\'m building an application with wxPython and a Deep Learning model that I created using Tensorflow. The design pattern that I\'m using is MVC. My problem is that the deep
Just for fun and because I prefer the answer that kbr85 gave to my simplistic first answer, here's a Threaded variant with a gauge
in the statusbar
and a Busy cursor, although my screenshot program didn't pick it up.
There's a Stop
button and the statusbar
is removed once the load finishes.
Rather than use pubsub
, I've used a wxpython event
to communicate.
import wx
import time
from threading import Thread
import wx.lib.newevent
progress_event, EVT_PROGRESS_EVENT = wx.lib.newevent.NewEvent()
load_status=["Model Loading","Model Loaded","Model Cancelled"]
class Model(Thread):
def __init__(self,parent):
Thread.__init__(self)
'''This thread simulates the loading of tensorflow'''
self.stopthread = 0
self.target = parent
self.start()
def run(self):
while not self.stopthread:
for i in range(20):
if self.stopthread:
break
time.sleep(0.5)
evt = progress_event(count=i, status=self.stopthread)
wx.PostEvent(self.target, evt)
if self.stopthread == 0:
self.stopthread = 1
evt = progress_event(count=i, status=self.stopthread)
wx.PostEvent(self.target, evt)
def terminate(self):
self.stopthread = 2
class View(wx.Frame):
def __init__(self, parent, title):
super(View, self).__init__(parent, title=title, size=(400, 400))
self.InitUI()
def InitUI(self):
self.vbox = wx.BoxSizer(wx.VERTICAL)
self.fgs = wx.FlexGridSizer(6, 2, 10, 25)
id = wx.StaticText(self, label="ID:")
firstName = wx.StaticText(self, label="First name:")
lastName = wx.StaticText(self, label="Last name:")
self.idTc = wx.TextCtrl(self)
self.firstNameTc = wx.TextCtrl(self)
self.lastNameTc = wx.TextCtrl(self)
self.stop = wx.Button(self, -1, "Stop Load")
self.fgs.AddMany([id, (self.idTc, 1, wx.EXPAND),
firstName, (self.firstNameTc, 1, wx.EXPAND),
lastName, (self.lastNameTc, 1, wx.EXPAND),
(self.stop,1,wx.EXPAND)])
self.vbox.Add(self.fgs, proportion=1, flag=wx.ALL | wx.EXPAND,border=15)
#Bind to the progress event issued by the thread
self.Bind(EVT_PROGRESS_EVENT, self.OnProgress)
#Bind to Stop button
self.Bind(wx.EVT_BUTTON, self.OnStop)
#Bind to Exit on frame close
self.Bind(wx.EVT_CLOSE, self.OnExit)
self.SetSizer(self.vbox)
self.Layout()
self.statusbar = self.CreateStatusBar(2)
self.text = wx.StaticText(self.statusbar,-1,("No Model loaded"))
self.progress = wx.Gauge(self.statusbar, range=20)
sizer = wx.BoxSizer(wx.HORIZONTAL)
sizer.Add(self.text, 0, wx.ALIGN_TOP|wx.ALL, 5)
sizer.Add(self.progress, 1, wx.ALIGN_TOP|wx.ALL, 5)
self.statusbar.SetSizer(sizer)
wx.BeginBusyCursor()
self.loadthread = Model(self)
def OnProgress(self, event):
self.text.SetLabel(load_status[event.status])
#self.progress.SetValue(event.count)
#or for indeterminate progress
self.progress.Pulse()
if event.status != 0:
self.statusbar.Hide()
wx.EndBusyCursor()
self.Layout()
def OnStop(self, event):
if self.loadthread.isAlive():
self.loadthread.terminate() # Shutdown the thread
self.loadthread.join() # Wait for it to finish
def OnExit(self, event):
if self.loadthread.isAlive():
self.loadthread.terminate() # Shutdown the thread
self.loadthread.join() # Wait for it to finish
self.Destroy()
class Controller:
def __init__(self):
self.view = View(None, title='Test')
self.view.Show()
def main():
app = wx.App()
controller = Controller()
app.MainLoop()
if __name__ == '__main__':
main()