你可以使用_thread
模块和PyPubSub
模块以在模型加载期间保持主线程完全正常运行。
但是,请记住,如果您有wx.Button
在 GUI 中绑定到method A
and method A
需要加载完整模型才能正确运行,然后用户将能够单击wx.Button
并且程序可能会挂起,因为模型尚未完全加载。如果是这种情况,您可以使用以下方法Disable()
(在加载模型时)和Enable()
(加载模型后)以防止这种情况发生。
带注释的代码 (####)。
import wx
import time
import _thread
from pubsub import pub
class Model:
def __init__(self):
'''This part is simulating the loading of tensorflow'''
x = 0
while x < 15:
time.sleep(1)
print(x)
#### This is how you broadcast the 'Loading' message
#### from a different thread.
wx.CallAfter(pub.sendMessage, 'Loading', x=x)
x += 1
#### The same as before
wx.CallAfter(pub.sendMessage, 'Loading', x=x)
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
#### It needed to set the size of the panel to cover the frame
#### because it was not covering the entire frame before
masterPanel = wx.Panel(self, size=(400, 400))
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()
#### Create status bar to show loading progress.
self.statusbar = self.CreateStatusBar(1)
self.statusbar.SetStatusText('Loading model')
#### Set the size of the window because the status bar steals space
#### in the height direction.
self.SetSize(wx.DefaultCoord, 160)
#### Subscribe the class to the message 'Loading'. This means that every
#### time the meassage 'Loading' is broadcast the method
#### ShowLoadProgress will be executed.
pub.subscribe(self.ShowLoadProgress, 'Loading')
#### Start the thread that will load the model
_thread.start_new_thread(self.LoadModel, ('test',))
def LoadModel(self, test):
"""
Load the Model
"""
#### Change depending on how exactly are you going to create/load the
#### model
self.model = Model()
def ShowLoadProgress(self, x):
"""
Show the loading progress
"""
if x < 15:
self.statusbar.SetStatusText('Loading progress: ' + str(x))
else:
self.statusbar.SetStatusText('All loaded')
class Controller:
def __init__(self):
self.view = View(None, title='Test')
self.view.Show()
#### The line below is not needed now because the model is
#### loaded now from the thread started in View.InitUI
#self.model = Model()
def main():
app = wx.App()
controller = Controller()
app.MainLoop()
if __name__ == '__main__':
main()
如果您从内部方法加载模型class View
那么你将不需要 PyPubSub 模块,因为你可以调用wx.CallAfter(self.ShowLoadProgress, x)