谁能告诉我如何从wxPython框架中返回值?当用户单击close时,我会弹出一个消息对话框,询问他一个问题。我想将此消息对话框的返回代码返回给我的调用函数。
谢谢
发布于 2010-06-23 06:08:48
因为wxFrame具有通过app.MainLoop()功能处理的事件,所以获取wx.Frame()的返回值的唯一方法是捕获事件。
处理事件的标准实践通常来自类内部,该类派生自wx.Window本身(例如,Frame、Panel等)。由于您希望wx.Frame外部的代码接收在处理OnClose()事件时收集的信息,因此最好的方法是为帧注册一个事件处理程序。
wx.Window::PushEventHandler的文档可能是最好的资源,甚至wxpython wiki也有一篇关于如何做到这一点的很好的文章。在本文中,他们注册了一个自定义处理程序,它是“MouseDownTracker”的一个实例。与其在PushEventHandler调用中实例化,不如在调用之前实例化它,这样就可以保留EventHandler派生类的句柄。这样,你就可以在框架被销毁后检查你的派生EventHandler类变量,甚至允许派生类为你做一些特殊的事情。
以下是来自wx python wiki代码的改编(诚然,由于需要使用“调用”函数处理自定义事件的结果,因此有点复杂):
import sys
import wx
import wx.lib.newevent
(MyCustomEvent, EVT_CUSTOM) = wx.lib.newevent.NewEvent()
class CustomEventTracker(wx.EvtHandler):
def __init__(self, log, processingCodeFunctionHandle):
wx.EvtHandler.__init__(self)
self.processingCodeFunctionHandle = processingCodeFunctionHandle
self.log = log
EVT_CUSTOM(self, self.MyCustomEventHandler)
def MyCustomEventHandler(self, evt):
self.log.write(evt.resultOfDialog + '\n')
self.processingCodeFunctionHandle(evt.resultOfDialog)
evt.Skip()
class MyPanel2(wx.Panel):
def __init__(self, parent, log):
wx.Panel.__init__(self, parent)
self.log = log
def OnResults(self, resultData):
self.log.write("Result data gathered: %s" % resultData)
class MyFrame(wx.Frame):
def __init__(self, parent, ID=-1, title="", pos=wx.DefaultPosition, size=wx.DefaultSize, style=wx.DEFAULT_FRAME_STYLE):
wx.Frame.__init__(self, parent, ID, title, pos, size, style)
self.panel = panel = wx.Panel(self, -1, style=wx.TAB_TRAVERSAL | wx.CLIP_CHILDREN | wx.FULL_REPAINT_ON_RESIZE)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add((25, 25))
row = wx.BoxSizer(wx.HORIZONTAL)
row.Add((25,1))
m_close = wx.Button(self.panel, wx.ID_CLOSE, "Close")
m_close.Bind(wx.EVT_BUTTON, self.OnClose)
row.Add(m_close, 0, wx.ALL, 10)
sizer.Add(row)
self.panel.SetSizer(sizer)
def OnClose(self, evt):
dlg = wx.MessageDialog(self, "Do you really want to close this frame?", "Confirm Exit", wx.OK | wx.CANCEL | wx.ICON_QUESTION)
result = dlg.ShowModal()
dlg.Destroy()
if result == wx.ID_CANCEL:
event = MyCustomEvent(resultOfDialog="User Clicked CANCEL")
self.GetEventHandler().ProcessEvent(event)
else: # result == wx.ID_OK
event = MyCustomEvent(resultOfDialog="User Clicked OK")
self.GetEventHandler().ProcessEvent(event)
self.Destroy()
app = wx.App(False)
f2 = wx.Frame(None, title="Frame 1 (for feedback)", size=(400, 350))
p2 = MyPanel2(f2, sys.stdout)
f2.Show()
eventTrackerHandle = CustomEventTracker(sys.stdout, p2.OnResults)
f1 = MyFrame(None, title="PushEventHandler Tester (deals with on close event)", size=(400, 350))
f1.PushEventHandler(eventTrackerHandle)
f1.Show()
app.MainLoop()
发布于 2010-05-22 18:34:07
您可以通过单击对话框ShowModal方法中的OK、CANCEL按钮来获得结果。
给定对话框是其中一个wxPython对话框类的实例:
result = dialog.ShowModal()
if result == wx.ID_OK:
print "OK"
else:
print "Cancel"
dialog.Destroy()
发布于 2013-01-17 15:49:14
最初的问题晚了几年,但当我自己寻找这个问题的答案时,我偶然发现了一种内置的方法,可以从模式中获得返回值,而不会扰乱任何自定义事件的趣味性。我想我会在这里发布,以防其他人需要它。
很简单,就是这个人:
wxDialog::EndModal void EndModal(int retCode)
结束模式对话框,传递要从*wxDialog::ShowModal调用返回的值。*
使用上面的方法,你可以从对话框中返回任何你想要的东西。
一个示例用法是对wx.Dialog
进行子类化,然后将EndModal
函数放在按钮处理程序中。
class ProjectSettingsDialog(wx.Dialog):
def __init__(self):
wx.Dialog.__init__(self, None, -1, "Project Settings", size=(600,400))
sizer = wx.BoxSizer(wx.VERTICAL) #main sized
sizer.AddStretchSpacer(1)
msg = wx.StaticText(self, -1, label="This is a sample message")
sizer.Add(msg, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALL, 15)
horizontal_sizer = wx.BoxSizer(wx.HORIZONTAL)
okButton = wx.Button(self, -1, 'OK')
self.Bind(wx.EVT_BUTTON, self.OnOK, okButton)
cancelBtn = wx.Button(self, -1, "Cancel")
self.Bind(wx.EVT_BUTTON, self.OnCancel, cancelBtn)
horizontal_sizer.Add(okButton, 0, wx.ALIGN_LEFT)
horizontal_sizer.AddStretchSpacer(1)
horizontal_sizer.Add(cancelBtn, 0, wx.ALIGN_RIGHT)
sizer.Add(horizontal_sizer, 0)
sizer.AddStretchSpacer(1)
self.SetSizer(sizer)
def OnOK(self, event):
self.EndModal(wx.ID_OK) #returns numeric code to caller
self.Destroy()
def OnCancel(self, event):
self.EndModal(wx.ID_CANCEL) #returns numeric code to caller
self.Destroy()
(注意:我只是快速地完成了这段代码;没有测试sizers)
正如您所看到的,您所需要做的就是从按钮事件调用EndModal
,以将一个值返回给所产生的对话框。
https://stackoverflow.com/questions/2889255
复制相似问题