Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
wxPython:一个可折叠的面板小部件_Python_User Interface_Wxpython_Widget - Fatal编程技术网

wxPython:一个可折叠的面板小部件

wxPython:一个可折叠的面板小部件,python,user-interface,wxpython,widget,Python,User Interface,Wxpython,Widget,我有我的主程序窗口,我想做一个可折叠的面板。我的意思是,一个与窗户一侧对齐的面板,带有折叠/展开按钮。重要的是,当面板折叠/展开时,其他小部件会相应地改变大小,以利用它们所拥有的空间 如何做到这一点?如果您正确创建层次结构,wxPython(以及Swing和其他)的布局管理器应该能够为您做到这一点。假设它绑定到右侧,因此: +-----------------------------+ |+----------------+ +--------+| || | | T

我有我的主程序窗口,我想做一个可折叠的面板。我的意思是,一个与窗户一侧对齐的面板,带有折叠/展开按钮。重要的是,当面板折叠/展开时,其他小部件会相应地改变大小,以利用它们所拥有的空间


如何做到这一点?

如果您正确创建层次结构,wxPython(以及Swing和其他)的布局管理器应该能够为您做到这一点。假设它绑定到右侧,因此:

+-----------------------------+
|+----------------+ +--------+|
||                | | This is||
||                | | your   ||
||   Other stuff  | | panel  ||
||                | +--------+|
||                | +--------+|
||                | | Another||
||                | | panel  ||
|+----------------+ +--------+|
+-----------------------------+
如果布局正确,您将拥有一个具有两列的顶级布局,一列用于其他内容,另一列用于右侧容器

该容器将有自己的布局管理器,有两行,一行用于顶部面板,一行用于底部

这样,当您将顶部面板(可折叠的面板)调整为更短(折叠)或更高(展开)时,布局管理器应展开或收缩底部面板以适合


显然,您可以使用更复杂的布局管理器,我选择了最简单的布局管理器来说明如何在不干扰讨论的情况下使用列/行跨度和锚定等。您还可以通过反转窗口管理器(水平-垂直)来更改折叠方向。

这里是使用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()

另外,请查看wxPython演示中的wx.collapsablepane。

Toni Ruža的原始示例,稍作修改即可在4.0/Phoenix下工作。非常好的工作示例,谢谢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()

你是不是建议我自己写折叠/展开功能?我希望有一个现有的小部件。还有一件事:所谓“容器”,你的意思是
wx.Sizer
?因为我做了一个这样的小实验:我把两个窗口放在一个测码器中,然后调整其中一个窗口的大小。施胶器不适应。效果很好!现在,跟进问题。我想做一个小部件,将自动完成这项工作,所以我不必自己创建按钮和大小器。我该怎么着手做呢?在过去的一个小时里,我一直在尝试,但我遇到了一些问题:比方说,我叫我的班级FoldableIndowContainer(简称FWC)。我应该子类SplitterWindow吗?或者我应该将Window子类化,并在其中创建一个SplitterWindow?因为我尝试过这样做,但问题是,我如何将windows添加到FWC?我是说,谁是他们的父母,FWC还是里面的拆分窗口?请给出建议。您可以使用我从wx.Panel(而不是wx.Frame)中只给出子类的示例,并将拆分器窗口中的两个面板作为参数传递给init(使用它以便这些面板和您的FWC具有相同的父类)。另一个注意事项是,您可能会发现wx.SplitterWindow的setashGravity方法很有用。哦,是的,您应该在FWC的init中重新租用面板。我做了更改并更新了我的示例。