Вы можете использовать модуль _thread
и модуль PyPubSub
, чтобы сохранить основной поток полностью работоспособным во время загрузки модели.
Однако имейте в виду, что если в графическом интерфейсе пользователя wx.Button
привязано к method A
, а 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)