Come indicato nel mio previous question, sto cercando di creare qualcosa di simile a un wizard in funzione. Ho optato per un singolo frame con un sizer aggiunto ad esso. Costruisco pannelli per ciascuna delle schermate che vorrei che gli utenti vedessero, aggiungendole al sizer del frame, quindi passando da un pannello all'altro tramite .Hide()
in un pannello, quindi chiamando uno personalizzato .ShowYourself()
nel pannello successivo. Ovviamente, vorrei che i pulsanti rimanessero nello stesso posto in cui l'utente avanza nel processo.Perché fa .Hide() ing e .Show() ing Pannelli in wxPython Risultato in Sizer Cambiare il layout?
ho collegati tra loro due pannelli in un ciclo infinito dai loro pulsanti "Indietro" e "Avanti" in modo da poter vedere cosa sta succedendo. Il primo pannello sembra fantastico; Il codice di tom10 ha funzionato a quel livello, in quanto ha evitato il mio tentativo iniziale e stravagante con i confini che volavano in ogni direzione. E poi il secondo pannello sembra essersi ridotto al minimo. Quando torniamo al primo pannello, anche qui si è verificato il restringimento. Perché sembra perfetto nel primo pannello, ma non dopo il mio ritorno? Perché è necessario chiamare .Fit()
se non voglio un batuffolo di grigio da 10 pixel per 10 pixel? E se è necessario, perché .Fit()
dà risultati incoerenti?
Questo ciclo infinito sembra caratterizzare la mia esperienza con questo: ho risolto il layout su un pannello, solo per scoprire che il passaggio rovina il layout per altri pannelli. Ho risolto il problema utilizzando sizer_h.Add(self.panel1, 0)
anziché sizer_h.Add(self.panel1, 1, wx.EXPAND)
e ora i miei layout sono nuovamente disattivati.
Finora, la mia "soluzione" è quella di aggiungere uno mastersizer.SetMinSize((475, 592))
a ciascun master sizer di ogni pannello (commentato nel codice seguente). Questa è una soluzione cruda perché 1) ho dovuto trovare i numeri che funzionano per tentativi ed errori (-5 pixel per la larghezza, -28 pixel per l'altezza). 2) Non capisco perché il problema sottostante si verifica ancora.
Qual è la soluzione corretta, non brutta? Invece di aggiungere tutti i pannelli al sizer del frame in una sola volta, i pannelli di commutazione dovrebbero includere il pannello .Detach()
dal sizer del frame e quindi .Add()
il pannello successivo al sizer del frame? Esiste un metodo nascosto da qualche parte che ho perso sia in wxWidgets che nei documenti wxPython online?
Mi manca ovviamente qualcosa nel mio modello mentale di layout. Codice minimalista incollato di seguito.
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()
Vedrò questo. –
funziona correttamente su GTK –
Mi chiedo se ci sia qualche differenza funzionale tra GTK e Windows 7 (la mia piattaforma di destinazione) che non è stata considerata nella versione corrente di wxPython per Windows. È utile sapere, Steven. Significa che forse come sto pensando a questo non è completamente fuori. – MetaHyperBolic