如何使2个面板在wxpython上一个接一个地出现

How to make 2 panels appear one after the other on wxpython

我在主 window 中使用 wxpython 创建了 2 个面板(编码为 python 3.9)。 第一次处理后,我要求结果出现在第一个面板中,并显示这个面板。 然后第二个处理必须开始并在第二个面板中显示结果。 我的问题是 2 个面板在最后一次治疗完成时更新,而不是一个接一个地更新。 我试图等待第一种方法的 return 值但没有成功! 这是我的代码:

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

我不确定我是否正确理解了你的问题,但你误解了 python 的 time 函数的工作方式:如你所写它,计时器启动,但 python 继续处理函数中的其余代码。

最好使用 wx.Python 的计时器(请参阅 Mike Driscoll 的 tutorial)。

因此,在您的 Start 函数中使用:

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

更笼统地说,您已将框架设为面板的子项

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.

Overview of wxPython

您应该先定义一个框架并将所有面板作为框架的子项

这是它的样子

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