12 Stimmen

Warum führt .Hide()ing und .Show()ing Panels in wxPython dazu, dass der Sizer das Layout ändert?

Wie in meinem Bericht vorherige Frage Ich versuche, etwas zu machen, das von der Funktion her ein wenig an einen Zauberer erinnert. Ich habe auf einem einzigen Rahmen mit einem Sizer hinzugefügt, um es nieder. Ich baue Panels für jeden der Bildschirme, die ich möchte, dass Benutzer zu sehen, fügen Sie sie an den Rahmen der Sizer, dann wechseln Sie zwischen Panels durch .Hide() ein Panel zu erstellen und dann eine benutzerdefinierte .ShowYourself() auf der nächsten Tafel. Natürlich möchte ich, dass die Schaltflächen an der gleichen Stelle bleiben, wenn der Benutzer durch den Prozess fortschreitet.

Ich habe zwei Panels über die Schaltflächen "Zurück" und "Weiter" in einer Endlosschleife miteinander verbunden, damit Sie sehen können, was vor sich geht. Das erste Panel sieht großartig aus; tom10 Der Code hat auf dieser Ebene funktioniert, da er meinen anfänglichen, zu ausgefallenen Versuch mit den überall herumfliegenden Rändern umgangen hat. Und dann scheint das zweite Panel auf das absolute Minimum geschrumpft zu sein. Wenn wir zum ersten Panel zurückkehren, ist die Schrumpfung auch hier eingetreten. Warum sieht es auf der ersten Tafel gut aus, aber nicht, wenn ich dorthin zurückkehre? Warum ist der Aufruf von .Fit() notwendig, wenn ich kein 10 mal 10 Pixel großes graues Bündel haben möchte? Und wenn es notwendig ist, warum ist .Fit() inkonsistente Ergebnisse liefern?

Diese Endlosschleife scheint meine Erfahrung mit diesem Thema zu charakterisieren: Ich korrigiere das Layout für einen Bereich, um dann festzustellen, dass das Umschalten das Layout für andere Bereiche ruiniert. Ich behebe das Problem, indem ich sizer_h.Add(self.panel1, 0) anstelle von sizer_h.Add(self.panel1, 1, wx.EXPAND) und jetzt sind meine Layouts wieder weg.

Bislang besteht meine "Lösung" darin, eine mastersizer.SetMinSize((475, 592)) zum Master Sizer jedes Panels (im Code unten auskommentiert). Dies ist eine grobe Lösung, weil 1) Ich hatte, um die Zahlen zu finden, die durch Versuch und Irrtum (-5 Pixel für die Breite, -28 Pixel für die Höhe) funktionieren. 2) Ich verstehe nicht, warum das zugrunde liegende Problem immer noch auftritt.

Was ist die richtige, nicht hässliche Lösung? Anstatt alle Paneele auf einmal zur Rahmengröße hinzuzufügen, sollte das Wechseln der Paneele Folgendes beinhalten .Detach() dieses Paneel aus dem Sizer des Rahmens und dann .Add() das nächste Paneel in die Rahmengröße einfügen? Gibt es eine .JustMakeThisFillThePanel() Methode irgendwo versteckt, die ich sowohl in den wxWidgets- als auch in den wxPython-Dokumenten online übersehen habe?

Offensichtlich fehlt mir etwas in meinem mentalen Modell des Layouts. Minimalistischer Code unten eingefügt.

enter image description here

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X