Jak wspomniano w mojej previous question, próbuję zrobić coś nieco czarodziejskiego w funkcji. Ustaliłem jedną ramkę z dodanym sizerem. Buduję panele dla każdego z ekranów, które chciałbym zobaczyć dla użytkowników, dodam je do ramki, następnie przełączam między panelami przez .Hide()
na jednym panelu, a następnie wywołując niestandardowy .ShowYourself()
na następnym panelu. Oczywiście, chciałbym, aby przyciski pozostały w tym samym miejscu, w którym użytkownik przechodzi przez cały proces.Dlaczego robi .Hide() ing i .Show() ing Panele w wxPython Wynik w Sizer zmiany układu?
Połączyłem ze sobą dwa panele w nieskończonej pętli za pomocą przycisków "Wstecz" i "Następny", aby zobaczyć, co się dzieje. Pierwszy panel wygląda świetnie; Kod tom10 działał na tym poziomie, ponieważ zlikwidował moją początkową, nadmierną próbę graniczącą z każdym krajem. A potem drugi panel zdaje się zmniejszać do absolutnego minimum. Gdy wracamy do pierwszego panelu, nastąpiło tu również kurczenie się. Dlaczego wygląda dobrze na pierwszym panelu, ale nie po powrocie? Dlaczego konieczne jest wywołanie .Fit()
, jeśli nie chcę mieć 10-pikselowego szarego piksela o 10 pikseli? A jeśli jest to konieczne, dlaczego .Fit()
daje niespójne wyniki?
Ta nieskończona pętla wydaje się scharakteryzować moje doświadczenia z tym: Naprawiam układ na panelu, tylko po to, aby przełączanie niszczyło układ dla innych paneli. Naprawię ten problem, używając sizer_h.Add(self.panel1, 0)
zamiast sizer_h.Add(self.panel1, 1, wx.EXPAND)
, a teraz moje układy są wyłączone ponownie.
Do tej pory moje "rozwiązanie" polega na dodawaniu mastersizer.SetMinSize((475, 592))
do głównych rozmiarów paneli każdego panelu (skomentowano w poniższym kodzie). Jest to bardzo proste rozwiązanie, ponieważ 1) musiałem znaleźć numery, które działają metodą prób i błędów (-5 pikseli dla szerokości, -28 pikseli dla wysokości). 2) Nie rozumiem, dlaczego problem nadal występuje.
Jakie jest prawidłowe, nie brzydkie rozwiązanie? Zamiast dodawać wszystkie panele od razu do ramki, czy panele przełączające powinny obejmować panel z obramowaniem ramki, a następnie .Add()
następnego panelu do ramki? Czy istnieje metoda ukrywania gdzieś, o czym pominąłem zarówno w dokumentach wxWidgets, jak i wxPython w Internecie?
Najwyraźniej brakuje mi czegoś w moim mentalnym modelu układu. Minimalistyczny kod wklejony poniżej.
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()
Zajrzę do tego. –
działa poprawnie na GTK –
Zastanawiam się, czy jest jakaś funkcjonalna różnica między GTK i Windows 7 (moja platforma docelowa), która nie została uwzględniona w aktualnej wersji wxPython dla Windows. To bardzo przydatne, Steven. Oznacza to, że być może to, co o tym myślę, nie jest kompletne. – MetaHyperBolic