在 Python 中从 wxFormBuilder 访问特定的 sizer
Access a specific sizer from wxFormBuilder in Python
我已经使用 wxFormBuilder 构建了一个 GUI,并希望在 GUI 中动态添加按钮到 sizer。这是 wxFormBuilder 代码。
# -*- coding: utf-8 -*-
###########################################################################
## Python code generated with wxFormBuilder (version Jun 17 2015)
## http://www.wxformbuilder.org/
##
## PLEASE DO "NOT" EDIT THIS FILE!
###########################################################################
import wx
import wx.xrc
###########################################################################
## Class HighVoltage
###########################################################################
class HighVoltage ( wx.Frame ):
def __init__( self, parent ):
wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = wx.EmptyString, pos = wx.DefaultPosition, size = wx.Size( 1031,530 ), style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL )
self.SetSizeHintsSz( wx.DefaultSize, wx.DefaultSize )
self.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_ACTIVECAPTION ) )
bSizer84 = wx.BoxSizer( wx.VERTICAL )
self.m_panel70 = wx.Panel( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
bSizer85 = wx.BoxSizer( wx.HORIZONTAL )
self.m_staticText79 = wx.StaticText( self.m_panel70, wx.ID_ANY, u"HV Documentation", wx.DefaultPosition, wx.DefaultSize, 0 )
self.m_staticText79.Wrap( -1 )
self.m_staticText79.SetFont( wx.Font( 20, 70, 90, 92, False, "Century Gothic" ) )
bSizer85.Add( self.m_staticText79, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 )
bSizer85.AddSpacer( ( 0, 0), 1, wx.EXPAND, 5 )
self.m_bitmap24 = wx.StaticBitmap( self.m_panel70, wx.ID_ANY, wx.Bitmap( u"LOGOtransSmall.png", wx.BITMAP_TYPE_ANY ), wx.DefaultPosition, wx.DefaultSize, 0 )
bSizer85.Add( self.m_bitmap24, 0, wx.ALL, 5 )
self.m_panel70.SetSizer( bSizer85 )
self.m_panel70.Layout()
bSizer85.Fit( self.m_panel70 )
bSizer84.Add( self.m_panel70, 0, wx.EXPAND |wx.ALL, 5 )
self.m_panel71 = wx.Panel( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
bSizer86 = wx.BoxSizer( wx.VERTICAL )
bSizer86.AddSpacer( ( 0, 0), 1, wx.EXPAND, 5 )
self.m_panel73 = wx.Panel( self.m_panel71, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
bSizer86.Add( self.m_panel73, 0, wx.EXPAND |wx.ALL, 5 )
self.m_panel71.SetSizer( bSizer86 )
self.m_panel71.Layout()
bSizer86.Fit( self.m_panel71 )
bSizer84.Add( self.m_panel71, 1, wx.EXPAND |wx.ALL, 5 )
self.m_panel72 = wx.Panel( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
bSizer87 = wx.BoxSizer( wx.HORIZONTAL )
bSizer87.AddSpacer( ( 0, 0), 1, wx.EXPAND, 5 )
self.m_button65 = wx.Button( self.m_panel72, wx.ID_ANY, u"Exit", wx.DefaultPosition, wx.DefaultSize, 0 )
bSizer87.Add( self.m_button65, 0, wx.ALL, 5 )
self.m_panel72.SetSizer( bSizer87 )
self.m_panel72.Layout()
bSizer87.Fit( self.m_panel72 )
bSizer84.Add( self.m_panel72, 0, wx.EXPAND |wx.ALL, 5 )
self.SetSizer( bSizer84 )
self.Layout()
self.Centre( wx.BOTH )
def __del__( self ):
pass
我想向 m_panel71 的子 bSizer86 添加按钮。
这是我到目前为止尝试过的方法。
class HvDocs(HighVoltage):
def __init__(self, parent):
HighVoltage.__init__(self, parent)
con = sqlite3.connect('hsmanagement.sqlite')
cur = con.execute('SELECT employee FROM employees WHERE hv=1 ORDER BY employee')
result = cur.fetchall()
con.close()
print result
sizer = self.GetSizer()
print type(sizer)
for f in range(0, len(result) ):
sizer.Add(wx.Button(self, label=str(result[f][0]), id=int(f), size=(200, 40)), 2, wx.CENTER)
我尝试了 sizer = self.GetSizer()
的一些变体,例如 sizer = self.m_panel71
和 sizer = self.GetSizer(self.m_panel71)
,但我所能做的就是将按钮添加到顶级 sizer84。我如何获得 bSizer86 的访问权?
请参阅以下最小示例,了解如何仅按名称查找面板、按钮和大小调整器。 wxFormBuilder 提供了为要跟踪的 GUI 元素设置 wx.Window
属性 window_name
的可能性。您应该能够找到您需要知道的控件,使用 parent.FindWindowByName(…)
这个名称而不依赖 class 属性。
import wx
TOK_PNL = 'window_name pnl'
TOK_BTN = 'window_name btn'
def on_btn(evt, parent):
btn = parent.FindWindowByName(TOK_BTN)
pnl = parent.FindWindowByName(TOK_PNL)
newbtn = wx.Button(pnl, -1, 'newbtn')
szsub = btn.GetContainingSizer()
szsub.Add(newbtn, 1, wx.EXPAND|wx.ALL, 4)
pnl.Layout()
class testfrm(wx.Frame):
def __init__(self, *args, **kwds):
wx.Frame.__init__(self, *args, **kwds)
pnl = wx.Panel(self, -1)
pnl.SetName(TOK_PNL)
btn = wx.Button(pnl, -1, 'Add Button')
btn.SetName(TOK_BTN)
szmain = wx.BoxSizer(wx.VERTICAL)
szsub = wx.BoxSizer(wx.HORIZONTAL)
szsub.Add(btn, 0, wx.EXPAND|wx.ALL, 4)
szmain.Add(szsub)
pnl.SetSizer(szmain)
the_parent = self
btn.Bind(wx.EVT_BUTTON, lambda evt: on_btn(evt, the_parent))
if __name__ == '__main__':
app = wx.App(redirect=False)
frm = testfrm(None, -1, 'testfrm')
frm.Show()
app.MainLoop()
在进一步挖掘和尝试之后,我终于用下面的代码解决了我的问题
sizer = self.m_button67.GetContainingSizer()
self.m_button67.Destroy()
self.m_staticText = wx.StaticText( self.m_panel74, wx.ID_ANY, label= "Ladder ID")
sizer.Add( self.m_staticText, 0, wx.ALL, 5 )
self.m_staticText = wx.StaticText( self.m_panel74, wx.ID_ANY, label= "Engineer")
sizer.Add( self.m_staticText, 0, wx.ALL, 5 )
self.m_staticText = wx.StaticText( self.m_panel74, wx.ID_ANY, label= "Description")
sizer.Add( self.m_staticText, 0, wx.ALL, 5 )
self.m_staticText = wx.StaticText( self.m_panel74, wx.ID_ANY, label= "Last Check")
sizer.Add( self.m_staticText, 0, wx.ALL, 5 )
self.m_staticText = wx.StaticText( self.m_panel74, wx.ID_ANY, label= "Next Check")
sizer.Add( self.m_staticText, 0, wx.ALL, 5 )
for f in range(0, len(ladder_data)):
self.m_button = wx.Button( self.m_panel74, id=int(f), label=str(ladder_data[f][0]))
self.Bind(wx.EVT_BUTTON, self.detect_on_button)
sizer.Add( self.m_button, 0, wx.ALL, 5 )
self.m_staticText = wx.StaticText( self.m_panel74, wx.ID_ANY, label= str(ladder_data[f][1]))
sizer.Add( self.m_staticText, 0, wx.ALL, 5 )
self.m_staticText = wx.StaticText( self.m_panel74, wx.ID_ANY, label= str(ladder_data[f][2]))
sizer.Add( self.m_staticText, 0, wx.ALL, 5 )
self.m_staticText = wx.StaticText( self.m_panel74, wx.ID_ANY, label= str(ladder_data[f][3]))
sizer.Add( self.m_staticText, 0, wx.ALL, 5 )
self.m_staticText = wx.StaticText( self.m_panel74, wx.ID_ANY, label= str(ladder_data[f][4]))
sizer.Add( self.m_staticText, 0, wx.ALL, 5 )
self.m_panel74.SetSizer( sizer )
self.m_panel74.Layout()
sizer.Fit( self.m_panel74 )
真正的关键是 GetContainingSizer() 的发现。
将其与在 wxFormBuilder 中设置的虚拟按钮一起使用 (self.m_button67)
sizer = self.m_button67.GetContainingSizer()
让你成为 sizer
使用
删除虚拟按钮
self.m_button67.Destroy()
添加小工具
self.m_staticText = wx.StaticText( self.m_panel74, wx.ID_ANY, label= str(ladder_data[f][1]))
sizer.Add( self.m_staticText, 0, wx.ALL, 5 )
布局完成
self.m_panel74.SetSizer( sizer )
self.m_panel74.Layout()
sizer.Fit( self.m_panel74 )
希望这对遇到同样问题的人有所帮助。
可能有点晚了,
我相信您在错误的元素上使用了 GetSizer。
尝试将 sizer = self.GetSizer()
切换为 sizer = self.m_panel71.GetSizer()
我已经使用 wxFormBuilder 构建了一个 GUI,并希望在 GUI 中动态添加按钮到 sizer。这是 wxFormBuilder 代码。
# -*- coding: utf-8 -*-
###########################################################################
## Python code generated with wxFormBuilder (version Jun 17 2015)
## http://www.wxformbuilder.org/
##
## PLEASE DO "NOT" EDIT THIS FILE!
###########################################################################
import wx
import wx.xrc
###########################################################################
## Class HighVoltage
###########################################################################
class HighVoltage ( wx.Frame ):
def __init__( self, parent ):
wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = wx.EmptyString, pos = wx.DefaultPosition, size = wx.Size( 1031,530 ), style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL )
self.SetSizeHintsSz( wx.DefaultSize, wx.DefaultSize )
self.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_ACTIVECAPTION ) )
bSizer84 = wx.BoxSizer( wx.VERTICAL )
self.m_panel70 = wx.Panel( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
bSizer85 = wx.BoxSizer( wx.HORIZONTAL )
self.m_staticText79 = wx.StaticText( self.m_panel70, wx.ID_ANY, u"HV Documentation", wx.DefaultPosition, wx.DefaultSize, 0 )
self.m_staticText79.Wrap( -1 )
self.m_staticText79.SetFont( wx.Font( 20, 70, 90, 92, False, "Century Gothic" ) )
bSizer85.Add( self.m_staticText79, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 )
bSizer85.AddSpacer( ( 0, 0), 1, wx.EXPAND, 5 )
self.m_bitmap24 = wx.StaticBitmap( self.m_panel70, wx.ID_ANY, wx.Bitmap( u"LOGOtransSmall.png", wx.BITMAP_TYPE_ANY ), wx.DefaultPosition, wx.DefaultSize, 0 )
bSizer85.Add( self.m_bitmap24, 0, wx.ALL, 5 )
self.m_panel70.SetSizer( bSizer85 )
self.m_panel70.Layout()
bSizer85.Fit( self.m_panel70 )
bSizer84.Add( self.m_panel70, 0, wx.EXPAND |wx.ALL, 5 )
self.m_panel71 = wx.Panel( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
bSizer86 = wx.BoxSizer( wx.VERTICAL )
bSizer86.AddSpacer( ( 0, 0), 1, wx.EXPAND, 5 )
self.m_panel73 = wx.Panel( self.m_panel71, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
bSizer86.Add( self.m_panel73, 0, wx.EXPAND |wx.ALL, 5 )
self.m_panel71.SetSizer( bSizer86 )
self.m_panel71.Layout()
bSizer86.Fit( self.m_panel71 )
bSizer84.Add( self.m_panel71, 1, wx.EXPAND |wx.ALL, 5 )
self.m_panel72 = wx.Panel( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
bSizer87 = wx.BoxSizer( wx.HORIZONTAL )
bSizer87.AddSpacer( ( 0, 0), 1, wx.EXPAND, 5 )
self.m_button65 = wx.Button( self.m_panel72, wx.ID_ANY, u"Exit", wx.DefaultPosition, wx.DefaultSize, 0 )
bSizer87.Add( self.m_button65, 0, wx.ALL, 5 )
self.m_panel72.SetSizer( bSizer87 )
self.m_panel72.Layout()
bSizer87.Fit( self.m_panel72 )
bSizer84.Add( self.m_panel72, 0, wx.EXPAND |wx.ALL, 5 )
self.SetSizer( bSizer84 )
self.Layout()
self.Centre( wx.BOTH )
def __del__( self ):
pass
我想向 m_panel71 的子 bSizer86 添加按钮。 这是我到目前为止尝试过的方法。
class HvDocs(HighVoltage):
def __init__(self, parent):
HighVoltage.__init__(self, parent)
con = sqlite3.connect('hsmanagement.sqlite')
cur = con.execute('SELECT employee FROM employees WHERE hv=1 ORDER BY employee')
result = cur.fetchall()
con.close()
print result
sizer = self.GetSizer()
print type(sizer)
for f in range(0, len(result) ):
sizer.Add(wx.Button(self, label=str(result[f][0]), id=int(f), size=(200, 40)), 2, wx.CENTER)
我尝试了 sizer = self.GetSizer()
的一些变体,例如 sizer = self.m_panel71
和 sizer = self.GetSizer(self.m_panel71)
,但我所能做的就是将按钮添加到顶级 sizer84。我如何获得 bSizer86 的访问权?
请参阅以下最小示例,了解如何仅按名称查找面板、按钮和大小调整器。 wxFormBuilder 提供了为要跟踪的 GUI 元素设置 wx.Window
属性 window_name
的可能性。您应该能够找到您需要知道的控件,使用 parent.FindWindowByName(…)
这个名称而不依赖 class 属性。
import wx
TOK_PNL = 'window_name pnl'
TOK_BTN = 'window_name btn'
def on_btn(evt, parent):
btn = parent.FindWindowByName(TOK_BTN)
pnl = parent.FindWindowByName(TOK_PNL)
newbtn = wx.Button(pnl, -1, 'newbtn')
szsub = btn.GetContainingSizer()
szsub.Add(newbtn, 1, wx.EXPAND|wx.ALL, 4)
pnl.Layout()
class testfrm(wx.Frame):
def __init__(self, *args, **kwds):
wx.Frame.__init__(self, *args, **kwds)
pnl = wx.Panel(self, -1)
pnl.SetName(TOK_PNL)
btn = wx.Button(pnl, -1, 'Add Button')
btn.SetName(TOK_BTN)
szmain = wx.BoxSizer(wx.VERTICAL)
szsub = wx.BoxSizer(wx.HORIZONTAL)
szsub.Add(btn, 0, wx.EXPAND|wx.ALL, 4)
szmain.Add(szsub)
pnl.SetSizer(szmain)
the_parent = self
btn.Bind(wx.EVT_BUTTON, lambda evt: on_btn(evt, the_parent))
if __name__ == '__main__':
app = wx.App(redirect=False)
frm = testfrm(None, -1, 'testfrm')
frm.Show()
app.MainLoop()
在进一步挖掘和尝试之后,我终于用下面的代码解决了我的问题
sizer = self.m_button67.GetContainingSizer()
self.m_button67.Destroy()
self.m_staticText = wx.StaticText( self.m_panel74, wx.ID_ANY, label= "Ladder ID")
sizer.Add( self.m_staticText, 0, wx.ALL, 5 )
self.m_staticText = wx.StaticText( self.m_panel74, wx.ID_ANY, label= "Engineer")
sizer.Add( self.m_staticText, 0, wx.ALL, 5 )
self.m_staticText = wx.StaticText( self.m_panel74, wx.ID_ANY, label= "Description")
sizer.Add( self.m_staticText, 0, wx.ALL, 5 )
self.m_staticText = wx.StaticText( self.m_panel74, wx.ID_ANY, label= "Last Check")
sizer.Add( self.m_staticText, 0, wx.ALL, 5 )
self.m_staticText = wx.StaticText( self.m_panel74, wx.ID_ANY, label= "Next Check")
sizer.Add( self.m_staticText, 0, wx.ALL, 5 )
for f in range(0, len(ladder_data)):
self.m_button = wx.Button( self.m_panel74, id=int(f), label=str(ladder_data[f][0]))
self.Bind(wx.EVT_BUTTON, self.detect_on_button)
sizer.Add( self.m_button, 0, wx.ALL, 5 )
self.m_staticText = wx.StaticText( self.m_panel74, wx.ID_ANY, label= str(ladder_data[f][1]))
sizer.Add( self.m_staticText, 0, wx.ALL, 5 )
self.m_staticText = wx.StaticText( self.m_panel74, wx.ID_ANY, label= str(ladder_data[f][2]))
sizer.Add( self.m_staticText, 0, wx.ALL, 5 )
self.m_staticText = wx.StaticText( self.m_panel74, wx.ID_ANY, label= str(ladder_data[f][3]))
sizer.Add( self.m_staticText, 0, wx.ALL, 5 )
self.m_staticText = wx.StaticText( self.m_panel74, wx.ID_ANY, label= str(ladder_data[f][4]))
sizer.Add( self.m_staticText, 0, wx.ALL, 5 )
self.m_panel74.SetSizer( sizer )
self.m_panel74.Layout()
sizer.Fit( self.m_panel74 )
真正的关键是 GetContainingSizer() 的发现。 将其与在 wxFormBuilder 中设置的虚拟按钮一起使用 (self.m_button67)
sizer = self.m_button67.GetContainingSizer()
让你成为 sizer 使用
删除虚拟按钮self.m_button67.Destroy()
添加小工具
self.m_staticText = wx.StaticText( self.m_panel74, wx.ID_ANY, label= str(ladder_data[f][1]))
sizer.Add( self.m_staticText, 0, wx.ALL, 5 )
布局完成
self.m_panel74.SetSizer( sizer )
self.m_panel74.Layout()
sizer.Fit( self.m_panel74 )
希望这对遇到同样问题的人有所帮助。
可能有点晚了,
我相信您在错误的元素上使用了 GetSizer。
尝试将 sizer = self.GetSizer()
切换为 sizer = self.m_panel71.GetSizer()