I created 2 panels in the main window with wxpython (coded with python 3.9). After the first processing I ask that the results appear in the first panel and that this one is displayed. Then the second treatment must start and display the result in the second panel. My problem is that the 2 panels update when the last treatment is finished and not one after the other. I tried to wait for a return value from the first method without success! Here is my code :
import wx
import wx.lib.scrolledpanel as scrolled
import wx.grid as grid
import time
class PanelChoice(wx.Panel):
def __init__(self, parent):
super(PanelChoice, self).__init__(parent)
self.SetBackgroundColour('#BDBDBD')
hbox = wx.BoxSizer(wx.HORIZONTAL)
self.label = wx.StaticText(self, label='Select data')
hbox.Add(self.label, 0, wx.LEFT | wx.ALIGN_CENTER_VERTICAL, 12)
list_choice = ['1', '2', '3', '4', '5', '6']
self.choice = wx.ComboBox(self, choices=list_choice)
self.choice.SetValue('1')
hbox.Add(self.choice, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 3)
self.btn_go = wx.Button(self, label='Go')
self.btn_go.Bind(wx.EVT_BUTTON, handler=self.Start)
hbox.Add(self.btn_go, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 12)
self.SetSizer(hbox)
def Start(self, event):
my_frame.panel_step1.FillGrid(17, 8)
my_frame.Layout()
time.sleep(3) # treatment simulation
my_frame.panel_step2.Show()
my_frame.panel_step2.FillGridPanel2()
my_frame.Layout()
class PanelStep1(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent)
self.SetBackgroundColour('green')
self.SetAutoLayout(1)
self.sizer = wx.BoxSizer(wx.VERTICAL)
hbox_title = wx.BoxSizer(wx.HORIZONTAL)
title = wx.StaticText(self, label='Title panel 1')
hbox_title.Add(title, 0, wx.LEFT | wx.TOP | wx.ALIGN_CENTER_VERTICAL, 6)
self.sizer.Add(hbox_title, 0, wx.LEFT, 0)
self.hbox_table = wx.BoxSizer(wx.HORIZONTAL)
self.sizer.Add(self.hbox_table, wx.ALL | wx.EXPAND, 0)
self.hbox_info = wx.BoxSizer(wx.HORIZONTAL)
self.info = wx.StaticText(self, label=' number of lines : ')
self.hbox_info.Add(self.info, 0, wx.LEFT | wx.EXPAND, 12)
self.sizer.Add(self.hbox_info, 0, wx.EXPAND, 0)
self.SetSizer(self.sizer)
self.Layout()
def FillGrid(self, nb_lines, nb_columns):
self.table = grid.Grid(self)
self.hbox_table.Add(self.table, 0, wx.LEFT | wx.EXPAND, 18)
self.table.CreateGrid(nb_lines, nb_columns)
nb_lines += 1
nb_columns += 1
for l in range(1, nb_lines):
for c in range(1, nb_columns):
self.table.SetCellValue(l-1, c-1, 'data ' + str(l) + '-' + str(c))
self.table.AutoSize()
self.table.SetRowLabelSize(50)
self.info.SetLabel(' number of lines : '+str(nb_lines))
self.Layout()
class PanelStep2(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent)
self.SetBackgroundColour('YELLOW')
self.SetAutoLayout(1)
self.sizer = wx.BoxSizer(wx.VERTICAL)
title = wx.StaticText(self, label='Table panel 2')
self.sizer.Add(title, 0, wx.LEFT | wx.TOP, 6)
self.info = wx.StaticText(self, label='Information on data processing ...')
self.info.SetFont(wx.Font(12, wx.SWISS, wx.NORMAL, wx.NORMAL, False))
self.sizer.Add(self.info, 0, wx.LEFT | wx.EXPAND, 18)
self.SetSizer(self.sizer)
def FillGridPanel2(self):
nb_lines = 27
nb_columns = 8
self.table = grid.Grid(self)
self.table.CreateGrid(nb_lines, nb_columns)
for r in range(nb_lines):
self.table.SetRowLabelValue(r, str(r+1)+' ')
self.table.SetRowLabelAlignment(wx.ALIGN_RIGHT, wx.ALIGN_CENTRE)
self.table.AutoSize()
self.table.SetRowLabelSize(30)
hbox_table = wx.BoxSizer(wx.HORIZONTAL)
hbox_table.Add(self.table, 0, wx.ALL | wx.EXPAND, 6)
self.sizer.Add(hbox_table, 0, wx.ALL | wx.EXPAND, 12)
self.Layout()
class MyApp(scrolled.ScrolledPanel):
def __init__(self, parent):
scrolled.ScrolledPanel.__init__(self, parent, -1)
font = wx.Font(12, wx.SWISS, wx.NORMAL, wx.NORMAL, False)
self.SetFont(font)
self.panel_choice = PanelChoice(self)
self.panel_step1 = PanelStep1(self)
self.panel_step2 = PanelStep2(self)
self.panel_step2.Hide()
self.sizer = wx.BoxSizer(wx.VERTICAL)
self.sizer.Add(self.panel_choice, 0, wx.ALL | wx.EXPAND)
self.sizer.Add(self.panel_step1, 0, wx.ALL | wx.EXPAND)
self.sizer.Add(self.panel_step2, 0, wx.ALL | wx.EXPAND)
self.SetSizer(self.sizer)
self.SetAutoLayout(True)
self.SetupScrolling()
if __name__ == "__main__":
app = wx.App(0)
screen_width, screen_height = wx.GetDisplaySize()
win_width = min(screen_width, 1280)
win_height = min(screen_height, 800)
frame = wx.Frame(None, wx.ID_ANY, title='My application', size=(win_width, win_height))
my_frame = MyApp(frame)
frame.CreateStatusBar()
frame.Show()
frame.Center()
app.MainLoop()
I'm not sure if I have understood your question correctly, but you have misunderstood the way that python's time function works: as you have written it, the timer is started, but python continues to process the rest of the code in the function.
Better to use wx.Python's Timer (see this tutorial from Mike Driscoll).
Therefore, in your Start function use:
def Start(self, event):
my_frame.panel_step1.FillGrid(17, 8)
my_frame.Layout()
self.timer = wx.Timer(self)
self.timer.StartOnce(3000)
self.Bind(wx.EVT_TIMER, self._display_second_panel, self.timer)
def _display_second_panel(self, event):
my_frame.panel_step2.Show()
my_frame.panel_step2.FillGridPanel2()
my_frame.Layout()
On a more general note, you have made the Frame a child of the panel
See the wxPython Panel documentation
A panel is a window on which controls are placed. It is usually placed within a frame. Its main feature over its parent class wx.Window is code for handling child windows and TAB traversal, which is implemented natively if possible (e.g. in wxGTK) or by wxWidgets itself otherwise.
You should define a frame first and have all of the panels as children of the frame
This is how it might look
import wx
import wx.lib.scrolledpanel as scrolled
import wx.grid as grid
class MainFrame(wx.Frame):
def __init__(self, *args, **kwargs):
super().__init__(None, *args, **kwargs)
screen_width, screen_height = wx.GetDisplaySize()
win_width = min(screen_width, 1280)
win_height = min(screen_height, 800)
self.Size = (win_width, win_height)
self.Title = 'Wx App'
self.panel = MainPanel(self)
self.panel_choice = PanelChoice(self)
self.panel_step1 = PanelStep1(self)
self.panel_step2 = PanelStep2(self)
self.panel_step2.Hide()
sizer = wx.BoxSizer(wx.VERTICAL)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(self.panel_choice, 0, wx.ALL | wx.EXPAND)
sizer.Add(self.panel_step1, 0, wx.ALL | wx.EXPAND)
sizer.Add(self.panel_step2, 0, wx.ALL | wx.EXPAND)
sizer.Add(self.panel)
self.SetSizer(sizer)
self.Center()
self.Show()
class MainPanel(scrolled.ScrolledPanel):
def __init__(self, parent):
scrolled.ScrolledPanel.__init__(self, parent, -1)
self.SetBackgroundColour('F00FF')
font = wx.Font(12, wx.SWISS, wx.NORMAL, wx.NORMAL, False)
self.SetFont(font)
self.SetAutoLayout(True)
self.SetupScrolling()
class PanelChoice(wx.Panel):
def __init__(self, parent):
super(PanelChoice, self).__init__(parent)
self.SetBackgroundColour('BLUE')
self.parent = parent
h_box = wx.BoxSizer(wx.HORIZONTAL)
self.label = wx.StaticText(self, label='Select data')
h_box.Add(self.label, 0, wx.LEFT | wx.ALIGN_CENTER_VERTICAL, 12)
list_choice = [str(choice) for choice in range(1, 7)]
self.choice = wx.ComboBox(self, choices=list_choice)
self.choice.SetValue('1')
h_box.Add(self.choice, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 3)
self.btn_go = wx.Button(self, label='Go')
self.btn_go.Bind(wx.EVT_BUTTON, handler=self.Start)
h_box.Add(self.btn_go, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 12)
self.SetSizer(h_box)
def Start(self, event):
self.parent.panel_step1.FillGrid(17, 8)
self.parent.Layout()
self.timer = wx.Timer(self)
self.timer.StartOnce(3000)
self.Bind(wx.EVT_TIMER, self._display_second_panel, self.timer)
def _display_second_panel(self, event):
self.parent.panel_step2.Show()
self.parent.panel_step2.FillGridPanel2()
self.parent.Layout()
class PanelStep1(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent)
self.SetBackgroundColour('green')
self.SetAutoLayout(1)
self.sizer = wx.BoxSizer(wx.VERTICAL)
h_box_title = wx.BoxSizer(wx.HORIZONTAL)
title = wx.StaticText(self, label='Title panel 1')
h_box_title.Add(title, 0, wx.LEFT | wx.TOP | wx.ALIGN_CENTER_VERTICAL, 6)
self.sizer.Add(h_box_title, 0, wx.LEFT, 0)
self.h_box_table = wx.BoxSizer(wx.HORIZONTAL)
self.sizer.Add(self.h_box_table, wx.ALL | wx.EXPAND, 0)
self.h_box_info = wx.BoxSizer(wx.HORIZONTAL)
self.info = wx.StaticText(self, label=' number of lines : ')
self.h_box_info.Add(self.info, 0, wx.LEFT | wx.EXPAND, 12)
self.sizer.Add(self.h_box_info, 0, wx.EXPAND, 0)
self.SetSizer(self.sizer)
self.Layout()
def FillGrid(self, nb_lines, nb_columns):
self.table = grid.Grid(self)
self.h_box_table.Add(self.table, 0, wx.LEFT | wx.EXPAND, 18)
self.table.CreateGrid(nb_lines, nb_columns)
nb_lines += 1
nb_columns += 1
for line_number in range(1, nb_lines):
for c in range(1, nb_columns):
self.table.SetCellValue(line_number-1, c-1, 'data ' + str(line_number) + '-' + str(c))
self.table.AutoSize()
self.table.SetRowLabelSize(50)
self.info.SetLabel(' number of lines : '+str(nb_lines))
self.Layout()
class PanelStep2(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent)
self.SetBackgroundColour('YELLOW')
self.SetAutoLayout(1)
self.sizer = wx.BoxSizer(wx.VERTICAL)
title = wx.StaticText(self, label='Table panel 2')
self.sizer.Add(title, 0, wx.LEFT | wx.TOP, 6)
self.info = wx.StaticText(self, label='Information on data processing ...')
self.info.SetFont(wx.Font(12, wx.SWISS, wx.NORMAL, wx.NORMAL, False))
self.sizer.Add(self.info, 0, wx.LEFT | wx.EXPAND, 18)
self.SetSizer(self.sizer)
def FillGridPanel2(self):
nb_lines = 27
nb_columns = 8
self.table = grid.Grid(self)
self.table.CreateGrid(nb_lines, nb_columns)
for r in range(nb_lines):
self.table.SetRowLabelValue(r, str(r+1)+' ')
self.table.SetRowLabelAlignment(wx.ALIGN_RIGHT, wx.ALIGN_CENTRE)
self.table.AutoSize()
self.table.SetRowLabelSize(30)
h_box_table = wx.BoxSizer(wx.HORIZONTAL)
h_box_table.Add(self.table, 0, wx.ALL | wx.EXPAND, 6)
self.sizer.Add(h_box_table, 0, wx.ALL | wx.EXPAND, 12)
self.Layout()
if __name__ == '__main__':
wx_app = wx.App()
MainFrame()
wx_app.MainLoop()