How to load a heavy model when using MVC design pattern

前端 未结 3 1229
终归单人心
终归单人心 2021-01-17 06:34

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

3条回答
  •  小蘑菇
    小蘑菇 (楼主)
    2021-01-17 07:01

    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()
    

提交回复
热议问题