Python 使用MVC设计模式时如何加载重型模型

Python 使用MVC设计模式时如何加载重型模型,python,model-view-controller,deep-learning,wxpython,Python,Model View Controller,Deep Learning,Wxpython,我正在用wxPython和我用Tensorflow创建的深度学习模型构建一个应用程序。我使用的设计模式是MVC。 我的问题是深度学习模型非常繁重,加载需要很长时间(大约2分钟),同时GUI挂起。 我创建了一个示例代码来描述这个过程。 以下是加载时GUI的外观: 这就是加载后GUI的外观: 问题是如何在加载模型时让应用程序运行? 我还想在GUI中添加一个状态行,指示模型正在加载或已经加载 我正在添加示例代码,演示如何构建我的应用程序 import wx import time class M

我正在用wxPython和我用Tensorflow创建的深度学习模型构建一个应用程序。我使用的设计模式是MVC。 我的问题是深度学习模型非常繁重,加载需要很长时间(大约2分钟),同时GUI挂起。 我创建了一个示例代码来描述这个过程。 以下是加载时GUI的外观:

这就是加载后GUI的外观:

问题是如何在加载模型时让应用程序运行? 我还想在GUI中添加一个状态行,指示模型正在加载或已经加载

我正在添加示例代码,演示如何构建我的应用程序

import wx
import time

class Model:
    def __init__(self):
        '''This part is simulating the loading of tensorflow'''
        x = 0
        while x < 15:
            time.sleep(1)
            print(x)
            x += 1

class View(wx.Frame):
    def __init__(self, parent, title):
        super(View, self).__init__(parent, title=title, size=(400, 400))
        self.InitUI()

    def InitUI(self):
        # Defines the GUI controls
        masterPanel = wx.Panel(self)
        masterPanel.SetBackgroundColour("gold")
        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.fgs.AddMany([id, (self.idTc, 1, wx.EXPAND),
                         firstName, (self.firstNameTc, 1, wx.EXPAND),
                         lastName, (self.lastNameTc, 1, wx.EXPAND)])
        self.vbox.Add(self.fgs, proportion=1, flag=wx.ALL | wx.EXPAND,
   border=15)
        self.SetSizer(self.vbox)
        self.vbox.Fit(self)
        self.Layout()

class Controller:
    def __init__(self):
        self.view = View(None, title='Test')
        self.view.Show()
        self.model = Model()

def main():
    app = wx.App()
    controller = Controller()
    app.MainLoop()

if __name__ == '__main__':
    main()
导入wx
导入时间
类别模型:
定义初始化(自):
“该部分模拟tensorflow的荷载”
x=0
当x<15时:
时间。睡眠(1)
打印(x)
x+=1
类视图(wx.Frame):
定义初始(自我、父母、头衔):
超级(视图,自我)。\uuuu初始化(父级,标题=标题,大小=(400400))
self.InitUI()
def InitUI(self):
#定义GUI控件
主面板=wx.面板(自)
主面板.镶嵌底色(“金色”)
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.fgs.AddMany([id,(self.idTc,1,wx.EXPAND),
名字,(self.firstNameTc,1,wx.EXPAND),
lastName,(self.lastNameTc,1,wx.EXPAND)])
self.vbox.Add(self.fgs,比例=1,标志=wx.ALL | wx.EXPAND,
边框=15)
self.SetSizer(self.vbox)
self.vbox.Fit(self)
self.Layout()
类控制器:
定义初始化(自):
self.view=view(无,title='Test')
self.view.Show()
self.model=model()
def main():
app=wx.app()
控制器=控制器()
app.MainLoop()
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
main()

您应该在
self.view.Show()
命令之后调用
wx.GetApp().Yield()
,该命令会立即将控制释放到
MainLoop

如果以增量方式执行模型加载代码,您也可以在加载期间定期调用Yield。
下面是一个简单的方法,告诉用户发生了什么事情。如果需要取消模型加载的选项,则必须将其包装在对话框中,假设它是增量加载的

import wx
import time

class Model:
    def __init__(self):
        '''This part is simulating the loading of tensorflow'''
        x = 0
        #If the model load is perform in increments you could call wx.Yield
        # between the increments.
        while x < 15:
            time.sleep(1)
            wx.GetApp().Yield()
            print(x)
            x += 1

class View(wx.Frame):
    def __init__(self, parent, title):
        super(View, self).__init__(parent, title=title, size=(400, 400))
        self.InitUI()

    def InitUI(self):
        # Defines the GUI controls
        #masterPanel = wx.Panel(self)
        #masterPanel.SetBackgroundColour("gold")
        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.fgs.AddMany([id, (self.idTc, 1, wx.EXPAND),
                         firstName, (self.firstNameTc, 1, wx.EXPAND),
                         lastName, (self.lastNameTc, 1, wx.EXPAND)])
        self.vbox.Add(self.fgs, proportion=1, flag=wx.ALL | wx.EXPAND,
   border=15)
        self.CreateStatusBar() # A Statusbar in the bottom of the window
        self.StatusBar.SetStatusText("No model loaded", 0)
        self.SetSizer(self.vbox)
        self.vbox.Fit(self)
        self.Layout()

class Controller:
    def __init__(self):
        self.view = View(None, title='Test')
        self.view.Show()
        self.view.SetStatusText("Model loading", 0)
        wait = wx.BusyInfo("Please wait, loading model...")
        #Optionally add parent to centre message on self.view
        #wait = wx.BusyInfo("Please wait, loading model...", parent=self.view)
        wx.GetApp().Yield()
        self.model = Model()
        self.view.SetStatusText("Model loaded", 0)
        del wait

def main():
    app = wx.App()
    controller = Controller()
    app.MainLoop()

if __name__ == '__main__':
    main()
导入wx
导入时间
类别模型:
定义初始化(自):
“该部分模拟tensorflow的荷载”
x=0
#如果以增量执行模型负载,则可以调用wx.Yield
#在增量之间。
当x<15时:
时间。睡眠(1)
wx.GetApp().Yield()
打印(x)
x+=1
类视图(wx.Frame):
定义初始(自我、父母、头衔):
超级(视图,自我)。\uuuu初始化(父级,标题=标题,大小=(400400))
self.InitUI()
def InitUI(self):
#定义GUI控件
#主面板=wx.面板(自)
#主面板.镶嵌底色(“金色”)
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.fgs.AddMany([id,(self.idTc,1,wx.EXPAND),
名字,(self.firstNameTc,1,wx.EXPAND),
lastName,(self.lastNameTc,1,wx.EXPAND)])
self.vbox.Add(self.fgs,比例=1,标志=wx.ALL | wx.EXPAND,
边框=15)
self.CreateStatusBar()#窗口底部的状态栏
self.StatusBar.SetStatusText(“未加载模型”,0)
self.SetSizer(self.vbox)
self.vbox.Fit(self)
self.Layout()
类控制器:
定义初始化(自):
self.view=view(无,title='Test')
self.view.Show()
self.view.SetStatusText(“模型加载”,0)
wait=wx.busynfo(“请稍候,正在加载模型…”)
#可选择在self.view上添加家长至中心消息
#wait=wx.busynfo(“请稍候,加载模型…”,parent=self.view)
wx.GetApp().Yield()
self.model=model()
self.view.SetStatusText(“模型加载”,0)
德尔等待
def main():
app=wx.app()
控制器=控制器()
app.MainLoop()
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
main()

您应该在
self.view.Show()
命令之后调用
wx.GetApp().Yield()
,该命令会立即将控制释放到
MainLoop

如果以增量方式执行模型加载代码,您也可以在加载期间定期调用Yield。
下面是一个简单的方法,告诉用户发生了什么事情。如果需要取消模型加载的选项,则必须将其包装在对话框中,假设它是增量加载的

import wx
import time

class Model:
    def __init__(self):
        '''This part is simulating the loading of tensorflow'''
        x = 0
        #If the model load is perform in increments you could call wx.Yield
        # between the increments.
        while x < 15:
            time.sleep(1)
            wx.GetApp().Yield()
            print(x)
            x += 1

class View(wx.Frame):
    def __init__(self, parent, title):
        super(View, self).__init__(parent, title=title, size=(400, 400))
        self.InitUI()

    def InitUI(self):
        # Defines the GUI controls
        #masterPanel = wx.Panel(self)
        #masterPanel.SetBackgroundColour("gold")
        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.fgs.AddMany([id, (self.idTc, 1, wx.EXPAND),
                         firstName, (self.firstNameTc, 1, wx.EXPAND),
                         lastName, (self.lastNameTc, 1, wx.EXPAND)])
        self.vbox.Add(self.fgs, proportion=1, flag=wx.ALL | wx.EXPAND,
   border=15)
        self.CreateStatusBar() # A Statusbar in the bottom of the window
        self.StatusBar.SetStatusText("No model loaded", 0)
        self.SetSizer(self.vbox)
        self.vbox.Fit(self)
        self.Layout()

class Controller:
    def __init__(self):
        self.view = View(None, title='Test')
        self.view.Show()
        self.view.SetStatusText("Model loading", 0)
        wait = wx.BusyInfo("Please wait, loading model...")
        #Optionally add parent to centre message on self.view
        #wait = wx.BusyInfo("Please wait, loading model...", parent=self.view)
        wx.GetApp().Yield()
        self.model = Model()
        self.view.SetStatusText("Model loaded", 0)
        del wait

def main():
    app = wx.App()
    controller = Controller()
    app.MainLoop()

if __name__ == '__main__':
    main()
导入wx
导入时间
类别模型:
定义初始化(自):
“该部分模拟tensorflow的荷载”
x=0
#如果以增量执行模型负载,则可以调用wx.Yield
#在增量之间。
当x<15时:
时间。睡眠(1)
wx.GetApp().Yield()
打印(x)
x+=1
类视图(wx.Frame):
定义初始(自我、父母、头衔):
超级(视图,自我)。\uuuu初始化\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu=(
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()