我正在尝试学习Python和WxPython。我多年来一直是SAS程序员。这个OOP的东西正在慢慢融合在一起,但我对很多概念仍然很模糊。下面是一段代码。我试图使用按钮单击来创建另一个类的实例。具体来说 - 我将主面板放在一个类中,当用户单击主面板上的某个菜单项时,我想要实例化一个辅助面板。当辅助面板只是一个功能时,我完成了所有这些工作。我似乎无法在课堂上工作。
这是代码
import wx
class mainPanel(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, 'directEDGAR Supplemental Tools', size=(450, 450))
wx.Panel(self,-1)
wx.StaticText(self,-1, "This is where I will describe\n the purpose of these tools",(100,10))
menubar = wx.MenuBar()
parser = wx.Menu()
one =wx.MenuItem(parser,1,'&Extract Tables with One Heading or Label')
two =wx.MenuItem(parser,1,'&Extract Tables with Two Headings or Labels')
three =wx.MenuItem(parser,1,'&Extract Tables with Three Headings or Labels')
four =wx.MenuItem(parser,1,'&Extract Tables with Four Headings or Labels')
quit = wx.MenuItem(parser, 2, '&Quit\tCtrl+Q')
parser.AppendItem(one)
parser.AppendItem(two)
parser.AppendItem(three)
parser.AppendItem(four)
parser.AppendItem(quit)
menubar.Append(parser, '&Table Parsers')
textRip = wx.Menu()
section =wx.MenuItem(parser,1,'&Extract Text With Section Headings')
textRip.AppendItem(section)
menubar.Append(textRip, '&Text Rippers')
dataHandling = wx.Menu()
deHydrate =wx.MenuItem(dataHandling,1,'&Extract Data from Tables')
dataHandling.AppendItem(deHydrate)
menubar.Append(dataHandling, '&Data Extraction')
self.Bind(wx.EVT_MENU, self.OnQuit, id=2)
self.Bind(wx.EVT_MENU, self.subPanel(None, -1, 'TEST'),id=1)
self.SetMenuBar(menubar)
self.Centre()
self.Show(True)
def OnQuit(self, event):
self.Close()
class subPanel(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, 'directEDGAR Supplemental Tools', size=(450, 450))
wx.Panel(self,-1)
wx.StaticText(self,-1, "This is where I will describe\n the purpose of these tools",(100,10))
getDirectory = wx.Button(panel, -1, "Get Directory Path", pos=(20,350))
getDirectory.SetDefault()
getTerm1 = wx.Button(panel, -1, "Get Search Term", pos=(20,400))
getTerm1.SetDefault()
#getDirectory.Bind(wx.EVT_BUTTON, getDirectory.OnClick, getDirectory.button)
self.Centre()
self.Show(True)
app = wx.App()
mainPanel(None, -1, '')
app.MainLoop()
答案 0 :(得分:1)
我不知道wxWidgets,但基于我对Python的了解,我猜你需要改变:
self.Bind(wx.EVT_MENU, self.subPanel(None, -1, 'TEST'),id=1)
为:
self.Bind(wx.EVT_MENU, subPanel(None, -1, 'TEST'),id=1)
“subPanel”是一个全局定义的类,不是“self”的成员(它是一个mainPanel)。
编辑:啊,“Bind”似乎将一个动作绑定到一个函数,所以你需要给它一个创建另一个类的函数。请尝试以下方法。它仍然不起作用,但至少它现在在子面板创建过程中崩溃。
self.Bind(wx.EVT_MENU, lambda(x): subPanel(None, -1, 'TEST'),id=1)
答案 1 :(得分:1)
您应该处理按钮单击事件,并在按钮处理程序中创建面板(就像您已经使用OnQuit方法一样)。
我认为以下代码基本上就是您所追求的 - 在单击按钮/选择菜单项时创建一个新框架。
import wx
class MyFrame(wx.Frame):
def __init__(self, parent, title="My Frame", num=1):
self.num = num
wx.Frame.__init__(self, parent, -1, title)
panel = wx.Panel(self)
button = wx.Button(panel, -1, "New Panel")
button.SetPosition((15, 15))
self.Bind(wx.EVT_BUTTON, self.OnNewPanel, button)
self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
# Now create a menu
menubar = wx.MenuBar()
self.SetMenuBar(menubar)
# Panel menu
panel_menu = wx.Menu()
# The menu item
menu_newpanel = wx.MenuItem(panel_menu,
wx.NewId(),
"&New Panel",
"Creates a new panel",
wx.ITEM_NORMAL)
panel_menu.AppendItem(menu_newpanel)
menubar.Append(panel_menu, "&Panels")
# Bind the menu event
self.Bind(wx.EVT_MENU, self.OnNewPanel, menu_newpanel)
def OnNewPanel(self, event):
panel = MyFrame(self, "Panel %s" % self.num, self.num+1)
panel.Show()
def OnCloseWindow(self, event):
self.Destroy()
def main():
application = wx.PySimpleApp()
frame = MyFrame(None)
frame.Show()
application.MainLoop()
if __name__ == "__main__":
main()
修改:添加了从菜单中执行此操作的代码。
答案 2 :(得分:0)
您需要在绑定表达式中使用事件处理程序
self.bind(wx.EVT_MENU, subPanel(None, -1, 'TEST'),id=1)
需要更改为:
self.bind(wx.EVT_MENU, <event handler>, <id of menu item>)
您的事件处理程序响应事件并实例化子面板:
def OnMenuItem(self, evt): #don't forget the evt
sp = SubPanel(self, wx.ID_ANY, 'TEST')
#I assume you will add it to a sizer
#if you aren't... you should
test_sizer.Add(sp, 1, wx.EXPAND)
#force the frame to refresh the sizers:
self.Layout()
或者,您可以在框架的__init__
中实例化子面板,并在实例化后调用subpanel.Hide()
,然后调用menuitem事件处理程序并调用面板上的显示subpanel.Show()
编辑:这里有一些代码会按照我的想法行事:
#!usr/bin/env python
import wx
class TestFrame(wx.Frame):
def __init__(self, parent, *args, **kwargs):
wx.Frame.__init__(self, parent, *args, **kwargs)
framesizer = wx.BoxSizer(wx.VERTICAL)
mainpanel = MainPanel(self, wx.ID_ANY)
self.subpanel = SubPanel(self, wx.ID_ANY)
self.subpanel.Hide()
framesizer.Add(mainpanel, 1, wx.EXPAND)
framesizer.Add(self.subpanel, 1, wx.EXPAND)
self.SetSizerAndFit(framesizer)
class MainPanel(wx.Panel):
def __init__(self, parent, *args, **kwargs):
wx.Panel.__init__(self, parent, *args, **kwargs)
panelsizer = wx.BoxSizer(wx.VERTICAL)
but = wx.Button(self, wx.ID_ANY, "Add")
self.Bind(wx.EVT_BUTTON, self.OnAdd, but)
self.panel_shown = False
panelsizer.Add(but, 0)
self.SetSizer(panelsizer)
def OnAdd(self, evt):
if not self.panel_shown:
self.GetParent().subpanel.Show()
self.GetParent().Fit()
self.GetParent().Layout()
self.panel_shown = True
else:
self.GetParent().subpanel.Hide()
self.GetParent().Fit()
self.GetParent().Layout()
self.panel_shown = False
class SubPanel(wx.Panel):
def __init__(self, parent, *args, **kwargs):
wx.Panel.__init__(self, parent, *args, **kwargs)
spsizer = wx.BoxSizer(wx.VERTICAL)
text = wx.StaticText(self, wx.ID_ANY, label='I am a subpanel')
spsizer.Add(text, 1, wx.EXPAND)
self.SetSizer(spsizer)
if __name__ == '__main__':
app = wx.App()
frame = TestFrame(None, wx.ID_ANY, "Test Frame")
frame.Show()
app.MainLoop()