如何在主框架中捕获子框架关闭事件?
How to capture sub frame close event in main frame?
在 WxPython 中,我在单击父框架 (ParentFrame) 的菜单上打开了一个新框架 (ChildFrame)。子框架用于将数据添加到配置文件。添加数据后(即关闭或单击 ChildFrame 中的按钮),我需要让父框架知道并刷新。如何在 wxPython 中做到这一点?
class ParentFrame(wx.Frame):
def __init__(self,parent,id):
...
self.Bind(wx.EVT_MENU, self.ShowChildFrame, None, ID_MENU_ITEM)
def ShowChildFrame(self, event):
self.child_frame= ChildFrame(parent=None, id=-1, title='New Frame Title')
self.Bind(self.child_frame.EVT_CLOSE, self.OnChildFrameClose) #this does not work since no EVT_CLOSE is available
self.child_frame.Show()
def OnChildFrameClose(self, event):
#do something
class ChildFrame(wx.Frame):
...
您可以使用 PubSub。它与 wxPython 一起提供并允许您订阅事件。这将使您订阅特定的 "close event"。然后在您的子框架中,您可以在捕获子框架的关闭事件时发布它正在关闭。以下教程可能有所帮助:
这是文章中的代码(注意:这需要 wxPython 2.9 或更高版本):
import wx
from wx.lib.pubsub import pub
########################################################################
class OtherFrame(wx.Frame):
""""""
#----------------------------------------------------------------------
def __init__(self):
"""Constructor"""
wx.Frame.__init__(self, None, wx.ID_ANY, "Secondary Frame")
panel = wx.Panel(self)
msg = "Enter a Message to send to the main frame"
instructions = wx.StaticText(panel, label=msg)
self.msgTxt = wx.TextCtrl(panel, value="")
closeBtn = wx.Button(panel, label="Send and Close")
closeBtn.Bind(wx.EVT_BUTTON, self.onSendAndClose)
sizer = wx.BoxSizer(wx.VERTICAL)
flags = wx.ALL|wx.CENTER
sizer.Add(instructions, 0, flags, 5)
sizer.Add(self.msgTxt, 0, flags, 5)
sizer.Add(closeBtn, 0, flags, 5)
panel.SetSizer(sizer)
#----------------------------------------------------------------------
def onSendAndClose(self, event):
"""
Send a message and close frame
"""
msg = self.msgTxt.GetValue()
pub.sendMessage("panelListener", message=msg)
pub.sendMessage("panelListener", message="test2", arg2="2nd argument!")
self.Close()
########################################################################
class MyPanel(wx.Panel):
""""""
#----------------------------------------------------------------------
def __init__(self, parent):
"""Constructor"""
wx.Panel.__init__(self, parent)
pub.subscribe(self.myListener, "panelListener")
btn = wx.Button(self, label="Open Frame")
btn.Bind(wx.EVT_BUTTON, self.onOpenFrame)
#----------------------------------------------------------------------
def myListener(self, message, arg2=None):
"""
Listener function
"""
print "Received the following message: " + message
if arg2:
print "Received another arguments: " + str(arg2)
#----------------------------------------------------------------------
def onOpenFrame(self, event):
"""
Opens secondary frame
"""
frame = OtherFrame()
frame.Show()
########################################################################
class MyFrame(wx.Frame):
""""""
#----------------------------------------------------------------------
def __init__(self):
"""Constructor"""
wx.Frame.__init__(self, None, title="New PubSub API Tutorial")
panel = MyPanel(self)
self.Show()
#----------------------------------------------------------------------
if __name__ == "__main__":
app = wx.App(False)
frame = MyFrame()
app.MainLoop()
或者,您可以创建 wx.Dialog
的子类并使用它代替框架。然后您可以模态显示对话框并像处理内置对话框一样捕获它的关闭。
您必须绑定到子框架而不是父框架并使用 wx.EVT_CLOSE 事件。
import wx
class ParentFrame(wx.Frame):
def __init__(self, *args, **kwargs):
super(ParentFrame, self).__init__(*args, **kwargs)
def ShowChildFrame(self):
self.child_frame = wx.Frame(self, title='New Frame Title')
self.child_frame.Bind(wx.EVT_CLOSE, self.OnChildFrameClose)
self.child_frame.Show()
def OnChildFrameClose(self, event):
print 'do something'
event.Skip()
app = wx.App()
frame = ParentFrame(None, title='Parent Frame')
frame.Show()
frame.ShowChildFrame()
app.MainLoop()
在 WxPython 中,我在单击父框架 (ParentFrame) 的菜单上打开了一个新框架 (ChildFrame)。子框架用于将数据添加到配置文件。添加数据后(即关闭或单击 ChildFrame 中的按钮),我需要让父框架知道并刷新。如何在 wxPython 中做到这一点?
class ParentFrame(wx.Frame):
def __init__(self,parent,id):
...
self.Bind(wx.EVT_MENU, self.ShowChildFrame, None, ID_MENU_ITEM)
def ShowChildFrame(self, event):
self.child_frame= ChildFrame(parent=None, id=-1, title='New Frame Title')
self.Bind(self.child_frame.EVT_CLOSE, self.OnChildFrameClose) #this does not work since no EVT_CLOSE is available
self.child_frame.Show()
def OnChildFrameClose(self, event):
#do something
class ChildFrame(wx.Frame):
...
您可以使用 PubSub。它与 wxPython 一起提供并允许您订阅事件。这将使您订阅特定的 "close event"。然后在您的子框架中,您可以在捕获子框架的关闭事件时发布它正在关闭。以下教程可能有所帮助:
这是文章中的代码(注意:这需要 wxPython 2.9 或更高版本):
import wx
from wx.lib.pubsub import pub
########################################################################
class OtherFrame(wx.Frame):
""""""
#----------------------------------------------------------------------
def __init__(self):
"""Constructor"""
wx.Frame.__init__(self, None, wx.ID_ANY, "Secondary Frame")
panel = wx.Panel(self)
msg = "Enter a Message to send to the main frame"
instructions = wx.StaticText(panel, label=msg)
self.msgTxt = wx.TextCtrl(panel, value="")
closeBtn = wx.Button(panel, label="Send and Close")
closeBtn.Bind(wx.EVT_BUTTON, self.onSendAndClose)
sizer = wx.BoxSizer(wx.VERTICAL)
flags = wx.ALL|wx.CENTER
sizer.Add(instructions, 0, flags, 5)
sizer.Add(self.msgTxt, 0, flags, 5)
sizer.Add(closeBtn, 0, flags, 5)
panel.SetSizer(sizer)
#----------------------------------------------------------------------
def onSendAndClose(self, event):
"""
Send a message and close frame
"""
msg = self.msgTxt.GetValue()
pub.sendMessage("panelListener", message=msg)
pub.sendMessage("panelListener", message="test2", arg2="2nd argument!")
self.Close()
########################################################################
class MyPanel(wx.Panel):
""""""
#----------------------------------------------------------------------
def __init__(self, parent):
"""Constructor"""
wx.Panel.__init__(self, parent)
pub.subscribe(self.myListener, "panelListener")
btn = wx.Button(self, label="Open Frame")
btn.Bind(wx.EVT_BUTTON, self.onOpenFrame)
#----------------------------------------------------------------------
def myListener(self, message, arg2=None):
"""
Listener function
"""
print "Received the following message: " + message
if arg2:
print "Received another arguments: " + str(arg2)
#----------------------------------------------------------------------
def onOpenFrame(self, event):
"""
Opens secondary frame
"""
frame = OtherFrame()
frame.Show()
########################################################################
class MyFrame(wx.Frame):
""""""
#----------------------------------------------------------------------
def __init__(self):
"""Constructor"""
wx.Frame.__init__(self, None, title="New PubSub API Tutorial")
panel = MyPanel(self)
self.Show()
#----------------------------------------------------------------------
if __name__ == "__main__":
app = wx.App(False)
frame = MyFrame()
app.MainLoop()
或者,您可以创建 wx.Dialog
的子类并使用它代替框架。然后您可以模态显示对话框并像处理内置对话框一样捕获它的关闭。
您必须绑定到子框架而不是父框架并使用 wx.EVT_CLOSE 事件。
import wx
class ParentFrame(wx.Frame):
def __init__(self, *args, **kwargs):
super(ParentFrame, self).__init__(*args, **kwargs)
def ShowChildFrame(self):
self.child_frame = wx.Frame(self, title='New Frame Title')
self.child_frame.Bind(wx.EVT_CLOSE, self.OnChildFrameClose)
self.child_frame.Show()
def OnChildFrameClose(self, event):
print 'do something'
event.Skip()
app = wx.App()
frame = ParentFrame(None, title='Parent Frame')
frame.Show()
frame.ShowChildFrame()
app.MainLoop()