gpt4 book ai didi

python - 约束 wxPython MultiSplitterWindow Pane

转载 作者:太空宇宙 更新时间:2023-11-03 11:06:33 26 4
gpt4 key购买 nike

编辑:我将这个问题保持开放,因为它仍然是一个好问题,答案可能对其他人有用。但是,我会注意到,我通过对 AuiManager 使用完全不同的方法找到了解决问题的实际方法。 ;见 answer以下。

我正在处理 MultiSplitterWindow设置(在花费大量时间之后
对抗SashLayoutWindow布局怪癖)。不幸的是,当我
创建 MultiSplitterWindow ,我在拖动时看到了一些意外的行为
窗扇周围:窗扇可以拖动到包含窗口的外面
布局的方向。至少可以说,这是我想避免的行为。

这是基本设置(您可以在 wxPython 中确认以下行为
演示,只是替换 leftwinPanel1等,另请参见下面的示例应用程序)。我在哪里RootPanel/BoxSizer ,有一个面板
(或 Frame ,或任何您喜欢的容器元素)带有 BoxSizerMultiSplitterWindow添加 - 再次,就像在演示中一样。

+--------------------------------+
| RootPanel/BoxSizer |
|+------------------------------+|
|| MultiSplitterWindow ||
||+--------++--------++--------+||
||| Panel1 || Panel2 || Panel3 |||
||| || || |||
||+--------++--------++--------+||
|+------------------------------+|
+--------------------------------+

当你拖动时,你会得到这样的结果,其中 ~!指示面板“存在”但没有显示:
+--------------------------------+
| RootPanel/BoxSizer |
|+-------------------------------|~~~~~~~~~~~~~+
|| MultiSplitterWindow | !
||+-----------------++-----------|~~++~~~~~~~~+!
||| Panel1 || Panel2 | !! Panel3 !!
||| || | !! !!
||+-----------------++-----------|~~++~~~~~~~~+!
|+-------------------------------|~~~~~~~~~~~~~+
+--------------------------------+

如果此时,您拖动 RootPanel
整个面板集,您将再次看到所有面板。同样,如果您拖动 Panel1 上的宽度回落,您可以访问 Panel3 的腰带
再次(当然,假设 Panel2 还不算太宽)。而且,这
正是检查工具报告的情况: RootPanel保留其大小,但 MultiSplitterWindow增长超过了 RootPanel/BoxSizer .

使用检查工具进一步检查显示,虚拟和客户端宽度值均为 0,但实际大小值在超出范围时为负值(根据将其拖出窗口的相应像素数)。同样,这是疯狂的行为;我无法想象为什么有人会想要一个窗口以这种方式运行。

现在,如果按住 Shift使 _OnMouse方法在 MultiSplitterWindow调整邻居,这不会发生。因此,我的其中之一
方法是简单地覆盖该方法。它有效,但我更愿意
如果绝对必要,以这种方式覆盖方法。有没有其他更好的方法
解决这个问题?这似乎不是预期的或可取的
一般行为,所以我想有一种标准的方法来修复它。

我尝试过的其他事情:
  • 检查 MultiWindowSplitter 中的值的总和是否超过
    包含窗口的宽度,使用每个EVT_SPLITTER_SASH_POS_CHANGEDEVT_SPLITTER_SASH_POS_CHANGING事件,
    然后尝试通过以下方式解决问题:
  • 使用 event.Veto()调用
  • 使用 SetSashPosition()分离器上的方法
  • 覆盖 _OnMouse()使用正常行为的方法
    与按住 Shift 相关联 key 。这有效,但最终
    给我其他我不喜欢的结果。
  • 通过 SetMinimumPaneSize 设置最小 Pane 大小方法
  • MultiSplitterWindow 上设置最大大小通过 SetMaxSize()
  • RootPanel/BoxSizer 上设置最大大小同时使用 SetMaxSize()SetSizeHints()RootPanel .
  • 我什至用 wx.EVT_SIZE 的事件处理程序完成了这项工作在容器上使 RootPanel始终具有来自父框架元素的适当最大尺寸
  • 我为 MultiSplitterWindow 尝试了相同的事件处理方法,也无济于事。

  • 版本信息

    我已经确认这出现在 Windows 32 位和 OS X 64 位中,带有
    wxPython 的最新快照版本,针对 Python 2.7 和 3.3。

    工作示例(包括检查工具)

    下面基本上复制(并稍微简化)演示源。这是问题的有效演示。
    import wx, wx.adv
    import wx.lib.mixins.inspection as wit
    from wx.lib.splitter import MultiSplitterWindow


    class AppWInspection(wx.App, wit.InspectionMixin):
    def OnInit(self):
    self.Init() # enable Inspection tool
    return True


    class MultiSplitterFrame(wx.Frame):
    def __init__(self, *args, **kwargs):
    super().__init__(size=(800, 800), *args, **kwargs)
    self.SetMinSize((600, 600))

    self.top_sizer = wx.BoxSizer(orient=wx.HORIZONTAL)
    self.SetSizer(self.top_sizer)

    self.splitter = MultiSplitterWindow(parent=self, style=wx.SP_LIVE_UPDATE)
    self.top_sizer.Add(self.splitter, wx.SizerFlags().Expand().Proportion(1).Border(wx.ALL, 10))

    inner_panel1 = wx.Panel(parent=self.splitter)
    inner_panel1.SetBackgroundColour('#999980')
    inner_panel1_text = wx.StaticText(inner_panel1, -1, 'Inner Panel 1')
    inner_panel1.SetMinSize((100, -1))

    inner_panel2 = wx.Panel(parent=self.splitter)
    inner_panel2.SetBackgroundColour('#999990')
    inner_panel2_text = wx.StaticText(inner_panel2, -1, 'Inner Panel 2')
    inner_panel2.SetMinSize((100, -1))
    inner_panel2.SetMaxSize((100, -1))

    inner_panel3 = wx.Panel(parent=self.splitter)
    inner_panel3.SetBackgroundColour('#9999A0')
    inner_panel3_text = wx.StaticText(inner_panel3, -1, 'Inner Panel 3')
    inner_panel3.SetMinSize((100, -1))

    self.splitter.AppendWindow(inner_panel1)
    self.splitter.AppendWindow(inner_panel2)
    self.splitter.AppendWindow(inner_panel3)

    if __name__ == '__main__':
    app = AppWInspection(0)
    frame = MultiSplitterFrame(parent=None, title='MultiSplitterFrame Test')
    app.SetTopWindow(frame)
    frame.Show()
    app.MainLoop()

    最佳答案

    根据一个人的需要,使用一种可能的选项来代替自定义管理 MultiSplitterWindow (或 SashLayoutWindow 组合等)是高级用户界面套件的 AuiManager工具(Phoenix 之前版本的文档 here ;Phoenix 文档 here)。 AuiManager为你自动化很多这类事情。就我而言,我试图使用 MultiSplitterWindow作为控制相关 UI 的可折叠和可调整大小的面板的一种方式,因此 AuiManager非常合适:它已经内置了我需要的所有控件和约束。

    在这种情况下,所有需要做的就是创建一个 AuiManager实例

    (我将它留在这里作为答案,希望其他可能采取与我相同的幼稚方法的人会发现它很有用,但不选择它作为答案,因为它没有直接回答原始问题。)

    Phoenix下AUI的使用示例

    这个代码示例正是我试图用 MultiSplitterWindow 做的事情。 ,但由 AuiManager 自动管理.

    import wx, wx.adv
    import wx.lib.mixins.inspection as wit
    from wx.lib.agw import aui


    class AppWInspection(wx.App, wit.InspectionMixin):
    def OnInit(self):
    self.Init() # enable Inspection tool
    return True


    class AuiFrame(wx.Frame):
    def __init__(self, *args, **kwargs):
    super().__init__(size=(800, 800), *args, **kwargs)
    self.SetMinSize((600, 600))

    # Create an AUI Manager and tell it to manage this Frame
    self._manager = aui.AuiManager()
    self._manager.SetManagedWindow(self)

    inner_panel1 = wx.Panel(parent=self)
    inner_panel1.SetBackgroundColour('#999980')
    inner_panel1.SetMinSize((100, 100))
    inner_panel1_info = aui.AuiPaneInfo().Name('inner_panel1').Caption('Inner Panel 1').Left().\
    CloseButton(True).MaximizeButton(True).MinimizeButton(True).Show().Floatable(True)

    inner_panel2 = wx.Panel(parent=self)
    inner_panel2.SetBackgroundColour('#999990')
    inner_panel2_info = aui.AuiPaneInfo().Name('inner_panel2').Caption('Inner Panel 2').Left().Row(1).\
    Show().Floatable(False)

    inner_panel3 = wx.Panel(parent=self)
    inner_panel3.SetBackgroundColour('#9999A0')
    inner_panel3.SetMinSize((100, 100))
    inner_panel3_info = aui.AuiPaneInfo().Name('inner_panel3').Caption('Inner Panel 3').CenterPane()

    self._manager.AddPane(inner_panel1, inner_panel1_info)
    self._manager.AddPane(inner_panel2, inner_panel2_info)
    self._manager.AddPane(inner_panel3, inner_panel3_info)
    self._manager.Update()

    def __OnQuit(self, event):
    self.manager.UnInit()
    del self.manager
    self.Destroy()

    if __name__ == '__main__':
    app = AppWInspection(0)
    frame = AuiFrame(parent=None, title='AUI Manager Test')
    app.SetTopWindow(frame)
    frame.Show()
    app.MainLoop()

    关于python - 约束 wxPython MultiSplitterWindow Pane ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17818940/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com