我有一个对话框,里面有一个 ScrolledWindow,并且该 ScrolledWindow 中有一个动态数量的控件。
该对话框目前还不够大。我可以手动设置宽度和高度,但我不知道它们会是什么,所以我希望 sizer 自动设置大小,我相信这是 wxWidgets 希望你这样做的方式。
ScrolledWindow 有一个 sizer,它似乎可以正确计算尺寸要求。
我已将 ScrolledWindow 添加到 Dialog 的 sizer 中,但 Dialog 的 sizer 似乎没有考虑 ScrolledWindow 的大小来计算它的大小,因此它比 ScrolledWindow 的 sizer 认为的要小。
下面的日志演示了我的问题。为什么 scrolling_window 和 scrolling_window_sizer 认为它们的大小是 (267, 480),但 dialog_sizer 认为它可以逃脱 (210, 63) ?为什么?
scrolling window best size (14, 14)
scrolling window client size (267, 480)
scrolling window effect min size (14, 14)
scrolling window min client size (-1, -1)
scrolling window min size (-1, -1)
scrolling window size (267, 480)
scrolling window virtual size (267, 480)
scrolling window best virtual size (267, 480)
scrolling_window_sizer after layout fit GetSize (267, 480)
scrolling_window_sizer after layout fit GetMinSize (267, 480)
scrolling_window_sizer after layout fit ComputeFittingClientSize(self) (267, 480)
scrolling_window_sizer after layout fit ComputeFittingWindowSize(self) (267, 480)
dialog_sizer after add scrolling window GetSize (0, 0)
dialog_sizer after add scrolling window GetMinSize (24, 24)
dialog_sizer after add scrolling window ComputeFittingClientSize(self) (24, 24)
dialog_sizer after add scrolling window ComputeFittingWindowSize(self) (24, 24)
dialog_sizer after add buttons GetSize (0, 0)
dialog_sizer after add buttons GetMinSize (210, 63)
dialog_sizer after add buttons ComputeFittingClientSize(self) (210, 63)
dialog_sizer after add buttons ComputeFittingWindowSize(self) (210, 63)
dialog best size (210, 63)
dialog client size (210, 63)
dialog effect min size (210, 63)
dialog min client size (-1, -1)
dialog min size (-1, -1)
dialog size (210, 63)
dialog virtual size (210, 63)
dialog best virtual size (210, 63)
Traceback (most recent call last):
File "gui/klt_gui.py", line 208, in on_cancel_button_click
raise NotImplementedError
NotImplementedError
请注意,这是使用 wxPython 的 python,但我希望这是我使用 wxWidgets 而不是 wxPython 的一般问题。这是一大堆代码,但希望它足够简单易读。上面打印日志的行已用#! 标记。
This line: # 这行有问题。没有它,我认为sizer不会自动调整窗口。有了它,窗户就很小了。大小 = dialog_sizer.Fit(self) self.Layout()
我添加自己是为了让 sizer 重新调整对话框的大小。我不确定是否应该在布局前或布局后进行 Fit,但这似乎并不重要,因为如上面的日志所示,sizer 似乎没有考虑按钮,但没有考虑滚动窗户。
class AddEditCustomerDialog(wx.Dialog):
# Based on EditCustomerTemplateFrame generated by wxFrameBuilder
@staticmethod
def make_section_frame(parent, parent_sizer, section_name, field_names):
static_box = wx.StaticBox(parent, wx.ID_ANY, section_name)
section_static_box_sizer = wx.StaticBoxSizer(static_box, wx.VERTICAL)
flex_grid = wx.FlexGridSizer(0, 2, 5, 5)
flex_grid.AddGrowableCol(1)
flex_grid.SetFlexibleDirection(wx.HORIZONTAL)
flex_grid.SetNonFlexibleGrowMode(wx.FLEX_GROWMODE_ALL)
# do we need to keep these around? I guess for getting text etc
text_boxes = []
for field_name in field_names:
label = wx.StaticText(static_box, label=field_name)
label.Wrap(-1)
flex_grid.Add(label, 0,
wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT | wx.ALL,
5)
# value=, validator=, name =??
text_box = wx.TextCtrl(static_box)
flex_grid.Add(text_box, 1, wx.ALL | wx.EXPAND, 5)
section_static_box_sizer.Add(flex_grid, 1, wx.ALL | wx.EXPAND, 5)
parent_sizer.Add(section_static_box_sizer, 1, wx.ALL | wx.EXPAND, 5)
def add_dialog_buttons(self, add_or_edit, parent, parent_sizer):
# ok, cancel buttons:
dialog_buttons = wx.StdDialogButtonSizer()
self.save_button = wx.Button(parent, wx.ID_SAVE)
self.cancel_button = wx.Button(parent, wx.ID_CANCEL)
dialog_buttons.AddButton(self.save_button)
dialog_buttons.AddButton(self.cancel_button)
if add_or_edit == "Edit":
self.apply_button = wx.Button(parent, wx.ID_APPLY)
dialog_buttons.AddButton(self.apply_button)
dialog_buttons.Realize()
parent_sizer.Add(dialog_buttons, 0,
wx.ALIGN_BOTTOM | wx.ALIGN_RIGHT | wx.ALL | wx.EXPAND,
5)
# Connect Events
if add_or_edit == "Edit":
self.apply_button.Bind(wx.EVT_BUTTON, self.on_apply_button_click)
self.cancel_button.Bind(wx.EVT_BUTTON, self.on_cancel_button_click)
self.save_button.Bind(wx.EVT_BUTTON, self.on_save_button_click)
def __init__(self, parent, add_or_edit, config):
assert add_or_edit in ['Add', 'Edit']
wx.Dialog.__init__(self, parent,
title=add_or_edit + " Customer",
style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER | wx.STAY_ON_TOP)
self.SetSizeHintsSz(wx.DefaultSize, wx.DefaultSize)
dialog_sizer = wx.BoxSizer(wx.VERTICAL)
scrolling_window = wx.ScrolledWindow(self, wx.ID_ANY,
wx.DefaultPosition,
wx.DefaultSize,
wx.HSCROLL | wx.VSCROLL)
scrolling_window.SetScrollRate(5, 5)
scrolling_window_sizer = wx.BoxSizer(wx.VERTICAL)
self.make_section_frame(scrolling_window,
scrolling_window_sizer,
"LOL", ["test", "two", "three"])
self.make_section_frame(scrolling_window,
scrolling_window_sizer,
"rofl", ["12323 3 2 1 3 21 3 2", "abc", "123"])
self.make_section_frame(scrolling_window,
scrolling_window_sizer,
"heehhee", ["sd f ", "fdsf dsd ", "fff"])
scrolling_window.SetSizer(scrolling_window_sizer)
scrolling_window.Layout()
scrolling_window_sizer.Fit(scrolling_window)
self.print_window_sizes(scrolling_window, "scrolling window") #!
self.print_sizer(scrolling_window_sizer, scrolling_window,
"scrolling_window_sizer after layout fit") #!
dialog_sizer.Add(scrolling_window, 1, wx.ALL | wx.EXPAND, 5)
self.print_sizer(dialog_sizer, self,
"dialog_sizer after add scrolling window") #!
self.add_dialog_buttons(add_or_edit, self, dialog_sizer)
self.SetSizer(dialog_sizer)
self.print_sizer(dialog_sizer, self, "dialog_sizer after add buttons") #!
# This line is a problem. Without it, I don't think the sizer will automatically adjust the window. With it, the window is tiny.
size = dialog_sizer.Fit(self)
self.Layout()
self.Centre(wx.BOTH)
self.print_window_sizes(self, "dialog") #!
@staticmethod
def print_window_sizes(scrolling_window, window_name):
print(window_name, "best size", scrolling_window.GetBestSize())
print(window_name, "client size", scrolling_window.GetClientSize())
print(window_name, "effect min size", scrolling_window.GetEffectiveMinSize())
print(window_name, "min client size", scrolling_window.GetMinClientSize())
print(window_name, "min size", scrolling_window.GetMinSize())
print(window_name, "size", scrolling_window.GetSize())
print(window_name, "virtual size", scrolling_window.GetVirtualSize())
print(window_name, "best virtual size", scrolling_window.GetBestVirtualSize())
@staticmethod
def print_sizer(sizer, window, sizer_name):
print(sizer_name, "GetSize", sizer.GetSize())
print(sizer_name, "GetMinSize", sizer.GetMinSize())
print(sizer_name, "ComputeFittingClientSize(self)",
sizer.ComputeFittingClientSize(window))
print(sizer_name, "ComputeFittingWindowSize(self)",
sizer.ComputeFittingWindowSize(window))
def on_apply_button_click(self, event):
event.Skip()
raise NotImplementedError
def on_cancel_button_click(self, event):
event.Skip()
raise NotImplementedError
def on_save_button_click(self, event):
event.Skip()
raise NotImplementedError
app = wx.App(False)
AddEditCustomerDialog(None, "Add", None).Show(True)
app.MainLoop()
代码本身大部分是由 wxFormBuilder 生成的,我自己进行了修改以使其具有动态性。我假设 wxFormBuilder 编写的代码是正确的。但它就在这里,以防你认为它不正确并且以错误的顺序做某事,或者我修改得很糟糕;)
.fbp:https
://gist.github.com/Poddster/bf203294e0267d3da575f297fa5bb0a6
输出代码:https ://gist.github.com/Poddster/684896817452c3657ad65f86263a0a7a