There are two panels (one is a ScrolledPanel) in another panel. The bottom one is the ScrolledPanel, as soon as I call any method on the ScrolledPanel, such as panel.SetScrollRate(10, 10)
all the widgets disappear. Commenting out that line and all the widgets reappear. The top panel always displays fine.
在另一个面板中有两个面板(一个是ScrolledPanel)。底部是ScrolledPanel,只要我调用ScrolledPanel上的任何方法,比如panel.SetScrollRate(10,10),所有的小部件都会消失。注释掉该行,所有的小部件都会重新出现。顶部面板始终显示良好。
I just found that if I add the line below in the InspectionTool it starts to work, but if I include the line in the actual code I get no widgets as before.
obj.SetupScrolling(rate_x=10, rate_y=10, scrollToTop=False)
我刚刚发现,如果我在InspectionTool中添加以下行,它就会开始工作,但如果我在实际代码中包括该行,我就不会像以前一样得到任何小部件。Obj.SetupScrolling(rate_x=10,rate_y=10,scllToTop=False)
class FieldEdit(wx.Panel):
tmd = TomlMetaData()
def __init__(self, parent, *args, **kwargs):
super().__init__(parent, *args, **kwargs)
self.parent = parent
self.title = '''Add/Remove Fields'''
self._bg_color = (232, 213, 149)
w_bg_color = (222, 237, 230)
w_fg_color_0 = (50, 50, 204)
w_fg_color_1 = (197, 75, 108)
self.SetBackgroundColour(wx.Colour(*self._bg_color))
# Setup sizers.
sizer = wx.BoxSizer(wx.VERTICAL)
self.SetSizer(sizer)
# Setup panels.
kwargs = {'g_sizer': sizer, 'bg_color': self._bg_color,
'w_bg_color': w_bg_color, 'w_fg_color_0': w_fg_color_0,
'w_fg_color_1': w_fg_color_1}
panel_top = self._panel_top(kwargs)
sizer.Add(panel_top, 0, wx.EXPAND | wx.ALL, 6)
def _panel_top(self, kwargs):
panel = wx.Panel(self)
sizer = wx.BoxSizer(wx.VERTICAL)
panel.SetSizer(sizer)
grid_sizer = wx.GridBagSizer(vgap=2, hgap=2)
sizer.Add(grid_sizer, 0, wx.CENTER | wx.ALL, 6)
w_bg_color = kwargs['w_bg_color']
w_fg_color_0 = kwargs['w_fg_color_0']
w_fg_color_1 = kwargs['w_fg_color_1']
desc = wx.StaticText(panel, wx.ID_ANY, self._description, style=0)
desc.SetForegroundColour(wx.Colour(*w_fg_color_1))
desc.SetFont(wx.Font(10, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL,
wx.FONTWEIGHT_BOLD, 0, ''))
grid_sizer.Add(desc, (0, 0), (1, 3), wx.ALIGN_CENTER | wx.ALL, 6)
edit_names = self._edit_names
kwargs['edit_names'] = edit_names
edit_names.insert(0, 'Choose the Page to Edit')
combo_box = wx.ComboBox(panel, wx.ID_ANY, value=edit_names[0],
choices=edit_names, style=wx.TE_READONLY)
combo_box.SetBackgroundColour(wx.Colour(*w_bg_color))
combo_box.SetForegroundColour(wx.Colour(*w_fg_color_0))
combo_box.SetMinSize([196, 23])
self.Bind(wx.EVT_COMBOBOX, self.selection_closure(kwargs), combo_box)
grid_sizer.Add(combo_box, (1, 0), (1, 1),
wx.ALIGN_CENTER_VERTICAL | wx.ALL, 6)
field_desc = wx.StaticText(panel, wx.ID_ANY, "Enter a new field name:",
style=0)
field_desc.SetForegroundColour(wx.Colour(*w_fg_color_0))
field_desc.SetFont(
wx.Font(10, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL,
wx.FONTWEIGHT_BOLD, 0, ''))
grid_sizer.Add(field_desc, (2, 0), (1, 1), wx.ALL, 6)
field_name = wx.TextCtrl(panel, wx.ID_ANY, "", style=wx.TE_LEFT)
field_name.SetBackgroundColour(wx.Colour(*w_bg_color))
field_name.SetForegroundColour(wx.Colour(*w_fg_color_0))
field_name.SetMinSize((200, 23))
grid_sizer.Add(field_name, (2, 1), (1, 1), wx.ALL, 6)
add_button = wx.Button(panel, wx.ID_ANY, 'Add')
add_button.SetMinSize((50, 23))
add_button.SetBackgroundColour(wx.Colour(*w_bg_color))
add_button.SetForegroundColour(wx.Colour(*w_fg_color_0))
add_button.Bind(wx.EVT_BUTTON, self.add_button)
grid_sizer.Add(add_button, (2, 2), (1, 1), wx.ALL, 6)
line = wx.StaticLine(panel, wx.ID_ANY)
line.SetBackgroundColour(wx.Colour(*w_fg_color_0))
grid_sizer.Add(line, (3, 0), (1, 3), wx.EXPAND | wx.BOTTOM, 2)
return panel
def _panel_bot(self, kwargs):
panel = ScrolledPanel(self)
sizer = wx.BoxSizer(wx.VERTICAL)
panel.SetSizer(sizer)
grid_sizer = wx.GridBagSizer(vgap=2, hgap=2)
sizer.Add(grid_sizer, 0, wx.CENTER | wx.ALL, 6)
w_fg_color_0 = kwargs['w_fg_color_0']
w_fg_color_1 = kwargs['w_fg_color_1']
widget_labels = kwargs['widget_labels']
for idx, label in enumerate(widget_labels):
label = label.replace(r'\n', '\n')
widget = wx.StaticText(panel, wx.ID_ANY, label)
if label.endswith(':'):
span = 1
weight = 10
color = w_fg_color_0
else:
span = 2
weight = 12
color = w_fg_color_1
if '\n' in label:
width = 46
else:
width = 23
widget.SetFont(wx.Font(
weight, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL,
wx.FONTWEIGHT_BOLD, 0, ''))
widget.SetForegroundColour(wx.Colour(*color))
widget.SetMinSize((-1, width))
grid_sizer.Add(
widget, (idx, 0), (1, span),
wx.ALIGN_CENTER_VERTICAL | wx.LEFT | wx.RIGHT | wx.BOTTOM, 6)
#panel.SetScrollRate(10, 10) # When uncommented the widgets do not display.
kwargs['panel'] = panel
return panel
def selection_closure(self, kwargs):
def get_selection(event):
edit_names = kwargs['edit_names']
chosen = event.GetString().lower()
widget_labels = []
if edit_names[0].lower() != chosen:
items = self.tmd.panel_config.get(
chosen, {}).get('widgets', {})
for value in items.values():
if (not isinstance(value, list)
or value[0] != 'StaticText'): continue
args = self._find_dict(value).get('args', [])
widget_labels.append(args[2])
kwargs['widget_labels'] = widget_labels
self._create_widgets(kwargs)
else:
self._destroy_panel(kwargs.get('panel'), kwargs.get('g_sizer'))
return get_selection
def _create_widgets(self, kwargs):
g_sizer = kwargs['g_sizer']
panel = kwargs.get('panel')
# Destroy the previous panel if it exists.
self._destroy_panel(panel, g_sizer)
# Create a new panel.
panel = self._panel_bot(kwargs)
g_sizer.Add(panel, 0, wx.EXPAND | wx.ALL, 6)
def _destroy_panel(self, panel, g_sizer):
if g_sizer and panel:
g_sizer.Remove(1)
panel.Destroy()
g_sizer.Layout()
更多回答
I have fixed the primary issue. I had to do two things to get it to work properly.
我已经解决了主要问题。我必须做两件事才能让它正常工作。
First I added the line below at the end of the _create_widgets
method. It seems I needed a delay before I tried to call SetupScrolling
and 100ms did the trick.
首先,我在_Create_Widget方法的末尾添加了下面一行代码。在我尝试调用SetupScrolling之前,似乎需要延迟一段时间,100ms就成功了。
wx.CallLater(100, panel.SetupScrolling, rate_x=10, rate_y=10)
Second I had to create an event that runs when a resize event takes place. The line below was added to more or less the end of the _panel_bot
method.
其次,我必须创建一个在发生调整大小事件时运行的事件。下面的行或多或少被添加到_panel_bot方法的末尾。
self.Bind(wx.EVT_SIZE, self.resize_closure(panel, grid_sizer))
I tend to use closures when calling events so I can pass other variables into the event. The event code is below.
我倾向于在调用事件时使用闭包,这样我就可以将其他变量传递到事件中。事件代码如下。
def resize_closure(self, panel, grid_sizer):
def on_size_change(event):
width, height = grid_sizer.GetMinSize()
height += self.parent.statusbar_size[1]
panel.SetSizeHints(width, height)
return on_size_change
This seems to fix all the issues except one. I need to use a status bar at the bottom of the Frame, but when I scroll to the bottom of any panel the last widget is partially covered by the status bar. This is a different issue, however.
这似乎解决了所有问题,只有一个问题除外。我需要使用框架底部的状态栏,但当我滚动到任何面板的底部时,最后一个小部件部分被状态栏覆盖。然而,这是一个不同的问题。
更多回答
我是一名优秀的程序员,十分优秀!