Por que os painéis .Hide () e .Show () ing no wxPython resultam no Sizer alterando o layout?

Conforme mencionado no meupergunta anterior, Estou tentando criar algo ligeiramente semelhante a um assistente em função. Eu estabeleci um único quadro com um dimensionador adicionado a ele. Crio painéis para cada uma das telas que gostaria que os usuários visualizassem, os adicionava ao dimensionador do quadro e depois alternava entre os painéis.Hide()em um painel e, em seguida, chamando um.ShowYourself() no próximo painel. Obviamente, gostaria que os botões permanecessem no mesmo local em que o usuário progride no processo.

Liguei dois painéis em um loop infinito pelos botões "Voltar" e "Avançar" para que você possa ver o que está acontecendo. O primeiro painel parece ótimo;tom10O código funcionava nesse nível, pois evitava minha tentativa inicial e extravagante de fronteiras voando para todos os lados. E então o segundo painel parece ter diminuído ao mínimo. Quando voltamos ao primeiro painel, o encolhimento também ocorreu aqui. Por que fica bem no primeiro painel, mas não depois que volto para lá? Por que está ligando.Fit() necessário se eu não quiser um maço de 10 x 10 pixels de cinza? E se for necessário, por que.Fit() dar resultados inconsistentes?

Esse loop infinito parece caracterizar minha experiência com isso: eu corrijo o layout em um painel, apenas para descobrir que a alternância destrói o layout de outros painéis. Eu resolvo esse problema usandosizer_h.Add(self.panel1, 0) ao invés desizer_h.Add(self.panel1, 1, wx.EXPAND), e agora meus layouts estão desativados novamente.

Até agora, minha "solução" é adicionar ummastersizer.SetMinSize((475, 592)) ao dimensionador principal de cada painel (comentado no código abaixo). Esta é uma solução grosseira porque 1) tive que encontrar os números que funcionam por tentativa e erro (-5 pixels para a largura, -28 pixels para a altura). 2) Não entendo por que o problema subjacente ainda acontece.

Qual é a solução correta e não feia? Em vez de adicionar todos os painéis ao dimensionador do quadro de uma só vez, os painéis de comutação devem envolver.Detach()ao painel do dimensionador do quadro e depois.Add()o próximo painel para o dimensionador do quadro? Tem alguma.JustMakeThisFillThePanel() método escondido em algum lugar que eu perdi nos documentos wxWidgets e wxPython on-line?

Obviamente, estou sentindo falta de algo no meu modelo mental de layout. Código minimalista colado abaixo.

import wx
import sys


class My_App(wx.App):

    def OnInit(self):
        self.frame = My_Frame(None)
        self.frame.Show()
        self.SetTopWindow(self.frame)
        return True

    def OnExit(self):
        print 'Dying ...'


class My_Frame(wx.Frame):

    def __init__(self, image, parent=None,id=-1, title='Generic Title', pos=wx.DefaultPosition, style=wx.CAPTION | wx.STAY_ON_TOP):     

        size = (480, 620)
        wx.Frame.__init__(self, parent, id, 'Program Title', pos, size, style)

        sizer_h = wx.BoxSizer(wx.HORIZONTAL)

        self.panel0 = User_Interaction0(self)       
        sizer_h.Add(self.panel0, 1, wx.EXPAND)

        self.panel1 = User_Interaction1(self)       
        sizer_h.Add(self.panel1, 1, wx.EXPAND)

        self.SetSizer(sizer_h)

        self.panel0.ShowYourself()

    def ShutDown(self):
        self.Destroy()


class User_Interaction0(wx.Panel):

    def __init__(self, parent, id=-1):

        wx.Panel.__init__(self, parent, id)

        # master sizer for the whole panel
        mastersizer = wx.BoxSizer(wx.VERTICAL)
        #mastersizer.SetMinSize((475, 592))
        mastersizer.AddSpacer(15)


        # build the top row
        txtHeader = wx.StaticText(self, -1, 'Welcome to This Boring\nProgram', (0, 0))
        font = wx.Font(16, wx.DEFAULT, wx.NORMAL, wx.BOLD)
        txtHeader.SetFont(font)
        txtOutOf = wx.StaticText(self, -1, '1 out of 7', (0, 0))                
        rowtopsizer = wx.BoxSizer(wx.HORIZONTAL)
        rowtopsizer.Add(txtHeader, 3, wx.ALIGN_LEFT) 
        rowtopsizer.Add((0,0), 1)  
        rowtopsizer.Add(txtOutOf, 0, wx.ALIGN_RIGHT) 
        mastersizer.Add(rowtopsizer, 0, flag=wx.EXPAND | wx.LEFT | wx.RIGHT, border=15) 


        # build the middle row
        text = 'PANEL 0\n\n'
        text = text + 'This could be a giant blob of explanatory text.\n'

        txtBasic = wx.StaticText(self, -1, text)
        font = wx.Font(11, wx.DEFAULT, wx.NORMAL, wx.NORMAL)
        txtBasic.SetFont(font)
        mastersizer.Add(txtBasic, 1, flag=wx.EXPAND | wx.LEFT | wx.RIGHT, border=15)  


        # build the bottom row
        btnBack = wx.Button(self, -1, 'Back')
        self.Bind(wx.EVT_BUTTON, self.OnBack, id=btnBack.GetId())
        btnNext = wx.Button(self, -1, 'Next')
        self.Bind(wx.EVT_BUTTON, self.OnNext, id=btnNext.GetId())
        btnCancelExit = wx.Button(self, -1, 'Cancel and Exit')
        self.Bind(wx.EVT_BUTTON, self.OnCancelAndExit, id=btnCancelExit.GetId())
        rowbottomsizer = wx.BoxSizer(wx.HORIZONTAL)
        rowbottomsizer.Add(btnBack, 0, wx.ALIGN_LEFT)
        rowbottomsizer.AddSpacer(5)
        rowbottomsizer.Add(btnNext, 0)
        rowbottomsizer.AddSpacer(5)
        rowbottomsizer.AddStretchSpacer(1)
        rowbottomsizer.Add(btnCancelExit, 0, wx.ALIGN_RIGHT)
        mastersizer.Add(rowbottomsizer, flag=wx.EXPAND | wx.LEFT | wx.RIGHT, border=15)

        # finish master sizer
        mastersizer.AddSpacer(15)   
        self.SetSizer(mastersizer)

        self.Raise()
        self.SetPosition((0,0))
        self.Fit()  
        self.Hide()


    def ShowYourself(self):
        self.Raise()
        self.SetPosition((0,0))
        self.Fit()
        self.Show()


    def OnBack(self, event):
        self.Hide()
        self.GetParent().panel1.ShowYourself()

    def OnNext(self, event):
        self.Hide()
        self.GetParent().panel1.ShowYourself()

    def OnCancelAndExit(self, event):
        self.GetParent().ShutDown()


class User_Interaction1(wx.Panel):

    def __init__(self, parent, id=-1):

        wx.Panel.__init__(self, parent, id)

        # master sizer for the whole panel
        mastersizer = wx.BoxSizer(wx.VERTICAL)
        #mastersizer.SetMinSize((475, 592))
        mastersizer.AddSpacer(15)


        # build the top row
        txtHeader = wx.StaticText(self, -1, 'Read about This Boring\nProgram', (0, 0))
        font = wx.Font(16, wx.DEFAULT, wx.NORMAL, wx.BOLD)
        txtHeader.SetFont(font)
        txtOutOf = wx.StaticText(self, -1, '2 out of 7', (0, 0))                
        rowtopsizer = wx.BoxSizer(wx.HORIZONTAL)
        rowtopsizer.Add(txtHeader, 3, wx.ALIGN_LEFT) 
        rowtopsizer.Add((0,0), 1)  
        rowtopsizer.Add(txtOutOf, 0, wx.ALIGN_RIGHT) 
        mastersizer.Add(rowtopsizer, 0, flag=wx.EXPAND | wx.LEFT | wx.RIGHT, border=15) 


        # build the middle row
        text = 'PANEL 1\n\n'
        text = text + 'This could be a giant blob of boring text.\n'

        txtBasic = wx.StaticText(self, -1, text)
        font = wx.Font(11, wx.DEFAULT, wx.NORMAL, wx.NORMAL)
        txtBasic.SetFont(font)
        mastersizer.Add(txtBasic, 1, flag=wx.EXPAND | wx.LEFT | wx.RIGHT, border=15)  


        # build the bottom row
        btnBack = wx.Button(self, -1, 'Back')
        self.Bind(wx.EVT_BUTTON, self.OnBack, id=btnBack.GetId())
        btnNext = wx.Button(self, -1, 'Next')
        self.Bind(wx.EVT_BUTTON, self.OnNext, id=btnNext.GetId())
        btnCancelExit = wx.Button(self, -1, 'Cancel and Exit')
        self.Bind(wx.EVT_BUTTON, self.OnCancelAndExit, id=btnCancelExit.GetId())
        rowbottomsizer = wx.BoxSizer(wx.HORIZONTAL)
        rowbottomsizer.Add(btnBack, 0, wx.ALIGN_LEFT)
        rowbottomsizer.AddSpacer(5)
        rowbottomsizer.Add(btnNext, 0)
        rowbottomsizer.AddSpacer(5)
        rowbottomsizer.AddStretchSpacer(1)
        rowbottomsizer.Add(btnCancelExit, 0, wx.ALIGN_RIGHT)
        mastersizer.Add(rowbottomsizer, flag=wx.EXPAND | wx.LEFT | wx.RIGHT, border=15)

        # finish master sizer
        mastersizer.AddSpacer(15)   
        self.SetSizer(mastersizer)

        self.Raise()
        self.SetPosition((0,0))
        self.Fit()  
        self.Hide()


    def ShowYourself(self):
        self.Raise()
        self.SetPosition((0,0))
        self.Fit()
        self.Show()


    def OnBack(self, event):
        self.Hide()
        self.GetParent().panel0.ShowYourself()

    def OnNext(self, event):
        self.Hide()
        self.GetParent().panel0.ShowYourself()

    def OnCancelAndExit(self, event):
        self.GetParent().ShutDown()


def main():
    app = My_App(redirect = False)
    app.MainLoop()


if __name__ == '__main__':
    main()

questionAnswers(2)

yourAnswerToTheQuestion