Wie in meinem previous question verwiesen, versuche ich etwas etwas Zauberer-wie in Funktion zu machen. Ich habe mich auf einen einzelnen Rahmen mit einem Sizer, der hinzugefügt wird, festgelegt. Ich baue Panels für jeden der Bildschirme, die Benutzer sehen sollen, füge sie dem Frame-Sizer hinzu und wechsle dann zwischen den Panels um .Hide()
in einem Panel und rufe dann ein benutzerdefiniertes .ShowYourself()
auf dem nächsten Panel an. Offensichtlich möchte ich, dass die Schaltflächen am selben Ort bleiben, an dem der Benutzer den Prozess durchläuft.Warum .Hide() ing und .Show() ing Panels in wxPython Ergebnis im Sizer Ändern des Layouts?
Ich habe zwei Panels in einer Endlosschleife mit ihren "Zurück" und "Weiter" Tasten verbunden, so dass Sie sehen können, was vor sich geht. Das erste Panel sieht gut aus; Der Code von tom10 funktionierte auf dieser Ebene, da er meinen anfänglichen, übertriebenen Versuch mit Grenzen, die in alle Richtungen flogen, vermied. Und dann scheint das zweite Panel auf das absolute Minimum geschrumpft zu sein. Als wir zur ersten Platte zurückkehren, ist auch hier die Schrumpfung aufgetreten. Warum sieht es auf dem ersten Panel gut aus, aber nicht, nachdem ich dorthin zurückgekehrt bin? Warum muss .Fit()
aufgerufen werden, wenn ich kein 10 Pixel mal 10 Pixel graues Pixel möchte? Und wenn es notwendig ist, warum gibt .Fit()
inkonsistente Ergebnisse?
Diese Endlosschleife scheint meine Erfahrung mit diesem zu charakterisieren: Ich repariere das Layout auf einem Panel, nur um zu finden, dass das Umschalten das Layout für andere Panels ruiniert. Ich behebe dieses Problem, indem ich sizer_h.Add(self.panel1, 0)
anstelle von sizer_h.Add(self.panel1, 1, wx.EXPAND)
verwende, und jetzt sind meine Layouts wieder aus.
Bis jetzt ist meine "Lösung", einen mastersizer.SetMinSize((475, 592))
zu jedem Master-Sizer des Panels hinzuzufügen (auskommentiert in dem Code unten). Dies ist eine knifflige Lösung, denn 1) Ich musste die Zahlen finden, die durch Versuch und Irrtum funktionieren (-5 Pixel für die Breite, -28 Pixel für die Höhe). 2) Ich verstehe nicht, warum das zugrunde liegende Problem immer noch auftritt.
Was ist die richtige, nicht hässliche Lösung? Anstatt alle Panels gleichzeitig in den Frame-Sizer einzufügen, sollte das Panel beim Wechseln des Panels vom Frame-Sizer und .Add()
des nächsten Panels an den Frame-Sizer angeschlossen werden. Gibt es eine .JustMakeThisFillThePanel()
Methode, die irgendwo versteckt, die ich in den wxWidgets und den wxPython Dokumenten online verpasst habe?
Ich vermisse offensichtlich etwas in meinem mentalen Layout-Modell. Minimalistischer Code unten eingefügt.
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()
Ich werde das untersuchen. –
funktioniert es gut auf GTK –
Ich frage mich, ob es einige funktionale Unterschiede zwischen GTK und Windows 7 (meine Zielplattform) gibt, die in der aktuellen Version von WxPython für Windows nicht berücksichtigt wurde. Das ist praktisch zu wissen, Steven. Es bedeutet, dass es vielleicht nicht vollständig ist, wie ich darüber nachdenke. – MetaHyperBolic