wxPython:访问 wxFormBuilder 生成的 GUI 的 sizer 并替换 child
wxPython: access sizer of GUI generated by wxFormBuilder and replace child
我想在 MVC 的理念下构建我的应用程序,使用单独的 GUI 和控制器。此外,我有一个同事在图形任务方面比我好得多,我们想分配工作:他用wxFormBuilder构建图形部分,我构建应用程序的"machinery"。
当我生成 GUI 时,我想替换一些 wxFormbuilder 无法管理的元素:例如,wxObjectListView。我的想法是用一个普通的 wxListBox 创建一个 GUI,用主程序导入它,然后用一个 wxObjectListView 代替它。我不想直接修改wxFormBuilder生成的代码,因为我想保持与GUI编辑器的向后兼容性。
问题和问题是:从导入GUI的主程序中,如何访问包含列表的sizer,删除并用ObjectListView替换?像 sizer.Delete(list) 然后 sizer.Add(olv)...
举个例子:
wxFormBuilder 生成的 GUI 代码:带有列表和按钮的框架。
# -*- coding: utf-8 -*-
###########################################################################
## Python code generated with wxFormBuilder (version Sep 8 2010)
## http://www.wxformbuilder.org/
##
## PLEASE DO "NOT" EDIT THIS FILE!
###########################################################################
import wx
###########################################################################
## Class MyFrame1
###########################################################################
class MyFrame1 ( wx.Frame ):
def __init__( self, parent ):
wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = wx.EmptyString, pos = wx.DefaultPosition, size = wx.Size( 330,288 ), style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL )
self.SetSizeHintsSz( wx.DefaultSize, wx.DefaultSize )
fgSizer = wx.FlexGridSizer( 2, 1, 0, 0 )
fgSizer.AddGrowableCol( 0 )
fgSizer.AddGrowableRow( 0 )
fgSizer.SetFlexibleDirection( wx.BOTH )
fgSizer.SetNonFlexibleGrowMode( wx.FLEX_GROWMODE_SPECIFIED )
m_listBox1Choices = [ u"Row1", u"Row2" ]
self.m_listBox1 = wx.ListBox( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, m_listBox1Choices, 0 )
fgSizer.Add( self.m_listBox1, 1, wx.ALL|wx.EXPAND, 5 )
self.m_button1 = wx.Button( self, wx.ID_ANY, u"MyButton", wx.DefaultPosition, wx.DefaultSize, 0 )
fgSizer.Add( self.m_button1, 1, wx.ALL|wx.EXPAND, 5 )
self.SetSizer( fgSizer )
self.Layout()
self.Centre( wx.BOTH )
def __del__( self ):
pass
这里是主要代码,导入图形 class。
from __future__ import print_function
# -*- coding: utf-8 -*-
import wx
from olvGUI import MyFrame1
class Ventana(MyFrame1):
def inicia(self):
hijos = self.GetChildren()
for h in hijos:
print(h)
if __name__ == "__main__":
app = wx.App(False)
v = Ventana(None)
v.inicia()
v.Show()
app.MainLoop()
当我尝试访问 Frame 子项时,我只看到 "final" 对象,看不到 Sizer。
<wx._controls.ListBox; proxy of <Swig Object of type 'wxListBox *' at 0x1e0cea8> >
<wx._controls.Button; proxy of <Swig Object of type 'wxButton *' at 0x19a5f90> >
如果我想让它的元素可访问,也许 GUI 必须有另一个结构,但我不知道如何制作它。我已经尝试制作两级 sizer,最终结果是相同的:我可以访问最终元素,而不是 sizer。
您需要将 fgSizer
更改为 self.fgSizer
以便稍后访问。然后你可以使用 sizer 的 Remove
方法来删除小部件。有一种 Insert
方法可用于在其位置插入另一个小部件。
有关完整详细信息,请参阅有关 sizer 的文档:
因为您要删除和插入小部件,您很可能需要在该方法的末尾调用 Layout
。本文有例子:
最后,这里有一个获取 sizer 的例子:
import wx
########################################################################
class MyFrame(wx.Frame):
""""""
#----------------------------------------------------------------------
def __init__(self):
"""Constructor"""
wx.Frame.__init__(self, None, title='Test')
self.panel = wx.Panel(self)
sizer = wx.BoxSizer(wx.VERTICAL)
btn = wx.Button(self.panel, label="Get sizer")
btn.Bind(wx.EVT_BUTTON, self.onGetSizer)
sizer.Add(btn, 0, wx.ALL|wx.CENTER, 5)
self.panel.SetSizer(sizer)
self.Show()
#----------------------------------------------------------------------
def onGetSizer(self, event):
""""""
sizer = self.panel.GetSizer()
if __name__ == '__main__':
app = wx.App(False)
frame = MyFrame()
app.MainLoop()
以下是保存小部件索引的示例:
self.widget_dict = {}
some_boxsizer.Add(some_widget) # this is the first widget, so its ID is zero
self.widget_dict[some_widget] = 0
现在在您的事件处理程序中,您可以使用此字典来确定哪个小部件位于哪个索引中:
index = self.widget_dict[some_widget]
我想在 MVC 的理念下构建我的应用程序,使用单独的 GUI 和控制器。此外,我有一个同事在图形任务方面比我好得多,我们想分配工作:他用wxFormBuilder构建图形部分,我构建应用程序的"machinery"。
当我生成 GUI 时,我想替换一些 wxFormbuilder 无法管理的元素:例如,wxObjectListView。我的想法是用一个普通的 wxListBox 创建一个 GUI,用主程序导入它,然后用一个 wxObjectListView 代替它。我不想直接修改wxFormBuilder生成的代码,因为我想保持与GUI编辑器的向后兼容性。
问题和问题是:从导入GUI的主程序中,如何访问包含列表的sizer,删除并用ObjectListView替换?像 sizer.Delete(list) 然后 sizer.Add(olv)...
举个例子:
wxFormBuilder 生成的 GUI 代码:带有列表和按钮的框架。
# -*- coding: utf-8 -*-
###########################################################################
## Python code generated with wxFormBuilder (version Sep 8 2010)
## http://www.wxformbuilder.org/
##
## PLEASE DO "NOT" EDIT THIS FILE!
###########################################################################
import wx
###########################################################################
## Class MyFrame1
###########################################################################
class MyFrame1 ( wx.Frame ):
def __init__( self, parent ):
wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = wx.EmptyString, pos = wx.DefaultPosition, size = wx.Size( 330,288 ), style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL )
self.SetSizeHintsSz( wx.DefaultSize, wx.DefaultSize )
fgSizer = wx.FlexGridSizer( 2, 1, 0, 0 )
fgSizer.AddGrowableCol( 0 )
fgSizer.AddGrowableRow( 0 )
fgSizer.SetFlexibleDirection( wx.BOTH )
fgSizer.SetNonFlexibleGrowMode( wx.FLEX_GROWMODE_SPECIFIED )
m_listBox1Choices = [ u"Row1", u"Row2" ]
self.m_listBox1 = wx.ListBox( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, m_listBox1Choices, 0 )
fgSizer.Add( self.m_listBox1, 1, wx.ALL|wx.EXPAND, 5 )
self.m_button1 = wx.Button( self, wx.ID_ANY, u"MyButton", wx.DefaultPosition, wx.DefaultSize, 0 )
fgSizer.Add( self.m_button1, 1, wx.ALL|wx.EXPAND, 5 )
self.SetSizer( fgSizer )
self.Layout()
self.Centre( wx.BOTH )
def __del__( self ):
pass
这里是主要代码,导入图形 class。
from __future__ import print_function
# -*- coding: utf-8 -*-
import wx
from olvGUI import MyFrame1
class Ventana(MyFrame1):
def inicia(self):
hijos = self.GetChildren()
for h in hijos:
print(h)
if __name__ == "__main__":
app = wx.App(False)
v = Ventana(None)
v.inicia()
v.Show()
app.MainLoop()
当我尝试访问 Frame 子项时,我只看到 "final" 对象,看不到 Sizer。
<wx._controls.ListBox; proxy of <Swig Object of type 'wxListBox *' at 0x1e0cea8> >
<wx._controls.Button; proxy of <Swig Object of type 'wxButton *' at 0x19a5f90> >
如果我想让它的元素可访问,也许 GUI 必须有另一个结构,但我不知道如何制作它。我已经尝试制作两级 sizer,最终结果是相同的:我可以访问最终元素,而不是 sizer。
您需要将 fgSizer
更改为 self.fgSizer
以便稍后访问。然后你可以使用 sizer 的 Remove
方法来删除小部件。有一种 Insert
方法可用于在其位置插入另一个小部件。
有关完整详细信息,请参阅有关 sizer 的文档:
因为您要删除和插入小部件,您很可能需要在该方法的末尾调用 Layout
。本文有例子:
最后,这里有一个获取 sizer 的例子:
import wx
########################################################################
class MyFrame(wx.Frame):
""""""
#----------------------------------------------------------------------
def __init__(self):
"""Constructor"""
wx.Frame.__init__(self, None, title='Test')
self.panel = wx.Panel(self)
sizer = wx.BoxSizer(wx.VERTICAL)
btn = wx.Button(self.panel, label="Get sizer")
btn.Bind(wx.EVT_BUTTON, self.onGetSizer)
sizer.Add(btn, 0, wx.ALL|wx.CENTER, 5)
self.panel.SetSizer(sizer)
self.Show()
#----------------------------------------------------------------------
def onGetSizer(self, event):
""""""
sizer = self.panel.GetSizer()
if __name__ == '__main__':
app = wx.App(False)
frame = MyFrame()
app.MainLoop()
以下是保存小部件索引的示例:
self.widget_dict = {}
some_boxsizer.Add(some_widget) # this is the first widget, so its ID is zero
self.widget_dict[some_widget] = 0
现在在您的事件处理程序中,您可以使用此字典来确定哪个小部件位于哪个索引中:
index = self.widget_dict[some_widget]