2009-05-03 8 views
2

J'ai ma fenêtre de programme principale, et je voudrais faire un panneau pliable. Ce que je veux dire, c'est un panneau qui est aligné sur l'un des côtés de la fenêtre, avec un bouton de pliage/dépliage. Il est important que lorsque le panneau est plié/déplié, les autres widgets changent leur taille en conséquence pour profiter de l'espace dont ils disposent.wxPython: un widget de panneau pliable

Comment faire?

Répondre

4

Voici une manière utilisant wx.SplitterWindow

import wx, wx.calendar 


class FoldableWindowContainer(wx.Panel): 
    def __init__(self, parent, left, right): 
     wx.Panel.__init__(self, parent) 

     sizer = wx.BoxSizer(wx.HORIZONTAL) 
     self.SetSizer(sizer) 
     self.splitter = wx.SplitterWindow(self, style=wx.SP_LIVE_UPDATE) 
     left.Reparent(self.splitter) 
     right.Reparent(self.splitter) 
     self.left = left 
     self.right = right 
     self.splitter.SplitVertically(self.left, self.right) 
     self.splitter.SetMinimumPaneSize(50) 
     self.sash_pos = self.splitter.SashPosition 
     sizer.Add(self.splitter, 1, wx.EXPAND) 

     fold_button = wx.Button(self, size=(10, -1)) 
     fold_button.Bind(wx.EVT_BUTTON, self.On_FoldToggle) 
     sizer.Add(fold_button, 0, wx.EXPAND) 

    def On_FoldToggle(self, event): 
     if self.splitter.IsSplit(): 
      self.sash_pos = self.splitter.SashPosition 
      self.splitter.Unsplit() 
     else: 
      self.splitter.SplitVertically(self.left, self.right, self.sash_pos) 


class FoldTest(wx.Frame): 
    def __init__(self): 
     wx.Frame.__init__(self, None) 

     left = wx.Panel(self, style=wx.BORDER_SUNKEN) 
     right = wx.Panel(self, style=wx.BORDER_SUNKEN) 

     left_sizer = wx.BoxSizer(wx.VERTICAL) 
     left.SetSizer(left_sizer) 
     left_sizer.Add(wx.calendar.CalendarCtrl(left), 1, wx.EXPAND | wx.ALL, 5) 
     left_sizer.Add(wx.Button(left, label="Act"), 0, wx.EXPAND | wx.ALL, 5) 

     right_sizer = wx.BoxSizer(wx.VERTICAL) 
     right.SetSizer(right_sizer) 
     right_sizer.Add(
      wx.StaticText(right, label="Fold panel", style=wx.BORDER_RAISED), 
      1, wx.EXPAND | wx.ALL, 5 
     ) 

     FoldableWindowContainer(self, left, right) 


app = wx.PySimpleApp() 
app.TopWindow = FoldTest() 
app.TopWindow.Show() 
app.MainLoop() 

Aussi, consultez wx.CollapsiblePane dans les démos wxPython.

+0

Fonctionne bien! Maintenant, question de suivi. Je veux faire un widget qui le fera automatiquement, donc je n'aurai pas à créer le bouton et le calibreur moi-même. Comment dois-je m'y prendre pour le faire? J'ai essayé dans la dernière heure, et j'ai rencontré quelques problèmes: Disons que j'appelle ma classe FoldableWindowContainer (FWC pour faire court). Dois-je sous-diviser SplitterWindow? Ou devrais-je sous-classer Window, et créer un SplitterWindow à l'intérieur de celui-ci? Parce que j'ai essayé de le faire, mais le problème est, comment puis-je ajouter des fenêtres le FWC? Je veux dire, qui est leur parent, le FWC ou le SplitterWindow à l'intérieur de celui-ci? Veuillez nous aviser. –

+0

Vous pouvez utiliser l'exemple que j'ai donné seulement sous-classe de wx.Panel au lieu de wx.Frame et passer les deux panneaux qui vont dans la fenêtre de fractionnement comme arguments à __init__ (utilisez-le pour que ces panneaux et votre FWC aient le même parent) . Encore une chose sur une autre note, vous pourriez trouver la méthode SetSashGravity de wx.SplitterWindow utile. –

+0

Oh oui, et vous devriez réparer les panneaux dans le __init__ du FWC. J'ai fait les changements et mis à jour mon exemple. –

1

Les gestionnaires de disposition pour wxPython (et Swing et autres) devraient être en mesure de le faire pour vous si vous créez correctement la hiérarchie. Supposons qu'il est lié au côté droit, ainsi:

+-----------------------------+ 
|+----------------+ +--------+| 
||    | | This is|| 
||    | | your || 
|| Other stuff | | panel || 
||    | +--------+| 
||    | +--------+| 
||    | | Another|| 
||    | | panel || 
|+----------------+ +--------+| 
+-----------------------------+ 

Si votre mise en page est bien fait, vous aurez un schéma de haut niveau avec deux colonnes, une pour les autres choses et un pour le côté droit récipient.

Ce conteneur aura son propre gestionnaire de disposition avec deux lignes, une pour le panneau supérieur et une pour le bas. De cette façon, lorsque vous redimensionnez le panneau supérieur (votre pliable) pour le raccourcir (plier) ou le grandir (déplier), le gestionnaire de disposition doit agrandir ou contracter le panneau inférieur pour l'ajuster. De toute évidence, vous pouvez utiliser des gestionnaires de disposition plus compliqués, j'ai choisi les plus simples pour illustrer comment le faire sans encombrer la discussion avec des colonnes/ancres et des ancres et ainsi de suite. Vous pouvez également changer la direction du pliage en inversant les gestionnaires de fenêtres (horizontal < -> vertical).

+0

Suggérez-vous que j'écrive la fonctionnalité plier/déplier moi-même? J'espérais un widget existant. –

+0

Et une autre chose: Par "conteneur", voulez-vous dire 'wx.Sizer'? Parce que j'ai fait une petite expérience comme ça: j'ai mis deux fenêtres dans un calibreur, puis redimensionné l'une d'entre elles. Le calibreur ne s'est pas adapté. –

Questions connexes