Pregunta

Tengo mi ventana principal del programa y me gustaría hacer un panel plegable. Lo que quiero decir es, un panel que está alineado a uno de los lados de la ventana, con un botón de plegar / desplegar. Es importante que cuando el panel se pliegue / despliegue, los otros widgets cambien su tamaño en consecuencia para aprovechar el espacio que tienen.

¿Cómo hago esto?

¿Fue útil?

Solución

Aquí hay una forma de usar 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()

Además, consulte wx.CollapsiblePane en las demostraciones de wxPython.

Otros consejos

Los administradores de diseño para wxPython (y Swing y otros) deberían poder hacerlo por usted si crea la jerarquía correctamente. Supongamos que está unido al lado derecho, por lo tanto:

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

Si su diseño se realiza correctamente, tendrá un diseño de nivel superior con dos columnas, una para el otro material y otra para el contenedor del lado derecho.

Ese contenedor tendrá su propio administrador de diseño con dos filas, una para el panel superior y otra para la parte inferior.

De esa forma, cuando cambie el tamaño del panel superior (el plegable) para que sea más corto (plegado) o más alto (desplegado), el administrador de diseño debe expandir o contraer el panel inferior para que encaje.

Obviamente, puede usar administradores de diseño más complicados, he elegido los más simples para ilustrar cómo hacerlo sin saturar la discusión con espacios de columna / fila y anclas, etc. También puede cambiar la dirección de plegado invirtiendo los gestores de ventanas (horizontal & Lt; - & Gt; vertical).

El ejemplo original de Toni Ru & # 382; a, con ligeras modificaciones para trabajar bajo 4.0 / Phoenix. Muy buen ejemplo de trabajo, ¡gracias Toni!

import wx
import wx.adv


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.GetSashPosition()
        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.GetSashPosition()
            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.adv.CalendarCtrl(left), 1, wx.EXPAND | wx.ALL, 5)
        # left_sizer.Add(wx.Button(left, label="Act"), 0, wx.EXPAND | wx.ALL, 5)  # uncommented as unbound

        right_sizer = wx.BoxSizer(wx.VERTICAL)
        right.SetSizer(right_sizer)
        right_sizer.Add(wx.StaticText(right, label="Fold this panel using the thin vertical button on the right"),
                        1, wx.EXPAND | wx.ALL, 5)

        FoldableWindowContainer(self, left, right)


if __name__ == '__main__':
    app = wx.App()
    ex = FoldTest()
    ex.Show()
    app.MainLoop()
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top