Edit:我将问题保留原样,因为这仍然是一个好问题,而且答案可能对其他人有用。但是,我会注意到我找到了一个实际的解决方案my通过使用完全不同的方法来解决问题AuiManager
;看到answer https://stackoverflow.com/a/17837040/564181 below.
我正在研究一个MultiSplitterWindow
设置(花了很多时间之后
奋力对抗SashLayoutWindow
布局怪癖)。不幸的是,当我
创建一个MultiSplitterWindow
,拖动时我看到一些意外的行为
周围窗扇:可以将窗扇拖到包含窗口的外部
布局的方向。至少可以说,这是我想避免的行为。
这是基本设置(您可以在 wxPython 中确认以下行为
演示,只是替换leftwin
for Panel1
等,另请参阅下面的示例应用程序)。我在哪里有RootPanel/BoxSizer
,有一个面板
(或者Frame
,或者任何你喜欢的容器元素)BoxSizer
到其中MultiSplitterWindow
再次添加,如演示中所示。
+--------------------------------+
| RootPanel/BoxSizer |
|+------------------------------+|
|| MultiSplitterWindow ||
||+--------++--------++--------+||
||| Panel1 || Panel2 || Panel3 |||
||| || || |||
||+--------++--------++--------+||
|+------------------------------+|
+--------------------------------+
当你拖动时,你可能会得到这样的结果,其中~
and !
表明该面板“存在”但未显示:
+--------------------------------+
| RootPanel/BoxSizer |
|+-------------------------------|~~~~~~~~~~~~~+
|| MultiSplitterWindow | !
||+-----------------++-----------|~~++~~~~~~~~+!
||| Panel1 || Panel2 | !! Panel3 !!
||| || | !! !!
||+-----------------++-----------|~~++~~~~~~~~+!
|+-------------------------------|~~~~~~~~~~~~~+
+--------------------------------+
如果此时您将RootPanel
比
整体面板集,您将再次看到所有面板。同样,如果你拖动
宽度回到Panel1
,您可以访问窗扇Panel3
再次(假设Panel2
当然,还不算太宽)。而且,这
正是检查工具报告的情况:RootPanel
保持其大小,但MultiSplitterWindow
增长超过RootPanel/BoxSizer
.
使用检查工具进一步检查发现虚拟宽度和客户端宽度值均为 0,但实际大小值为negative(通过将其拖出窗口的相应像素数)每当它超出范围时。再说一次,这是一种疯狂的行为;我无法想象为什么有人会ever想要一个窗口有这样的行为。
现在,如果有人按住Shift
所以这样_OnMouse
中的方法MultiSplitterWindow
调整邻居,这种情况不会发生。因此,我的一位
方法是简单地覆盖该方法。它有效,但我更愿意
如果绝对必要的话,可以这样重写方法。还有其他更好的方法吗
解决这个问题?这似乎不是预期或可取的
一般行为,所以我想有一个标准的方法来修复它。
我尝试过的其他事情:
- Checking whether the sum of the values in the
MultiWindowSplitter
exceeds
the width of the containing window, using each of the
EVT_SPLITTER_SASH_POS_CHANGED
AND EVT_SPLITTER_SASH_POS_CHANGING
events,
and then trying to fix the issue by:
- 使用
event.Veto()
call
- 使用
SetSashPosition()
分离器上的方法
- 覆盖
_OnMouse()
方法使用通常的行为
与按住有关Shift
钥匙。这可行,但最终结果是
给我其他我不喜欢的结果。
- 通过设置最小窗格尺寸
SetMinimumPaneSize
method
- 设置最大尺寸
MultiSplitterWindow
via SetMaxSize()
- Setting the maximum size on
RootPanel/BoxSizer
using both SetMaxSize()
and SetSizeHints()
on the RootPanel
.
- 我什至用事件处理程序来完成此操作
wx.EVT_SIZE
在容器上,以便RootPanel
always具有来自父框架元素的适当的最大尺寸
- 我尝试了相同的事件处理方法
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()