问题
i am facing some issues to get return value from wxpython main fram.
my script:
import wx
import wx.xrc
class Email_template( wx.Frame ):
def __init__( self, parent, to, cc, subject, message_boby ):
app = wx.App(False)
wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = wx.EmptyString, pos = wx.DefaultPosition, size = wx.Size( 650,500 ), style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL )
self.SetSizeHintsSz( wx.DefaultSize, wx.DefaultSize )
self.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_INFOBK ) )
main_sizer = wx.FlexGridSizer( 0, 1, 0, 0 )
main_sizer.SetFlexibleDirection( wx.BOTH )
main_sizer.SetNonFlexibleGrowMode( wx.FLEX_GROWMODE_SPECIFIED )
header_sizer = wx.FlexGridSizer( 0, 2, 0, 0 )
header_sizer.SetFlexibleDirection( wx.BOTH )
header_sizer.SetNonFlexibleGrowMode( wx.FLEX_GROWMODE_SPECIFIED )
header_sizer_right = wx.FlexGridSizer( 0, 1, 0, 0 )
header_sizer_right.SetFlexibleDirection( wx.BOTH )
header_sizer_right.SetNonFlexibleGrowMode( wx.FLEX_GROWMODE_SPECIFIED )
self.mail_send_button = wx.Button( self, wx.ID_ANY, u"Send", wx.DefaultPosition, wx.Size( -1,50 ), 0 )
header_sizer_right.Add( self.mail_send_button, 0, wx.ALL, 5 )
self.mail_edit_button = wx.Button( self, wx.ID_ANY, u"Edit", wx.DefaultPosition, wx.Size( -1,50 ), 0 )
header_sizer_right.Add( self.mail_edit_button, 0, wx.ALL, 5 )
header_sizer.Add( header_sizer_right, 1, wx.EXPAND, 5 )
header_sizer_left = wx.FlexGridSizer( 0, 2, 0, 0 )
header_sizer_left.SetFlexibleDirection( wx.BOTH )
header_sizer_left.SetNonFlexibleGrowMode( wx.FLEX_GROWMODE_SPECIFIED )
self.from_staticText = wx.StaticText( self, wx.ID_ANY, u"From:", wx.DefaultPosition, wx.DefaultSize, 0 )
self.from_staticText.Wrap( -1 )
header_sizer_left.Add( self.from_staticText, 0, wx.ALL, 5 )
self.from_textCtrl = wx.TextCtrl( self, wx.ID_ANY, "from_mail@mymail.com", wx.DefaultPosition, wx.Size( 400,-1 ), 0 )
header_sizer_left.Add( self.from_textCtrl, 0, wx.ALL, 5 )
self.to_staticText = wx.StaticText( self, wx.ID_ANY, u"To:", wx.DefaultPosition, wx.DefaultSize, 0 )
self.to_staticText.Wrap( -1 )
header_sizer_left.Add( self.to_staticText, 0, wx.ALL, 5 )
self.to_textCtrl = wx.TextCtrl( self, wx.ID_ANY, to, wx.DefaultPosition, wx.Size( 400,-1 ), 0 )
header_sizer_left.Add( self.to_textCtrl, 0, wx.ALL, 5 )
self.cc_staticText = wx.StaticText( self, wx.ID_ANY, u"CC:", wx.DefaultPosition, wx.DefaultSize, 0 )
self.cc_staticText.Wrap( -1 )
header_sizer_left.Add( self.cc_staticText, 0, wx.ALL, 5 )
self.cc_textCtrl = wx.TextCtrl( self, wx.ID_ANY, cc, wx.DefaultPosition, wx.Size( 400,-1 ), 0 )
header_sizer_left.Add( self.cc_textCtrl, 0, wx.ALL, 5 )
self.subject_staticText = wx.StaticText( self, wx.ID_ANY, u"Subject:", wx.DefaultPosition, wx.DefaultSize, 0 )
self.subject_staticText.Wrap( -1 )
header_sizer_left.Add( self.subject_staticText, 0, wx.ALL, 5 )
self.subject_textCtrl = wx.TextCtrl( self, wx.ID_ANY, subject, wx.DefaultPosition, wx.Size( 400,-1 ), 0 )
header_sizer_left.Add( self.subject_textCtrl, 0, wx.ALL, 5 )
header_sizer.Add( header_sizer_left, 1, wx.EXPAND, 5 )
main_sizer.Add( header_sizer, 1, wx.EXPAND, 5 )
mail_sizer = wx.FlexGridSizer( 0, 1, 0, 0 )
mail_sizer.SetFlexibleDirection( wx.BOTH )
mail_sizer.SetNonFlexibleGrowMode( wx.FLEX_GROWMODE_SPECIFIED )
self.mail_textCtrl = wx.TextCtrl( self, wx.ID_ANY, message_boby, style=wx.TE_MULTILINE, size=( 600,330 ))
mail_sizer.Add( self.mail_textCtrl, 0, wx.ALL, 5 )
main_sizer.Add( mail_sizer, 1, wx.EXPAND, 5 )
self.to_textCtrl.Enable(False)
self.cc_textCtrl.Enable(False)
self.subject_textCtrl.Enable(False)
self.mail_textCtrl.Enable(False)
self.message_boby = message_boby
self.SetSizer( main_sizer )
self.Layout()
wx.EVT_BUTTON(self, self.mail_send_button.GetId(), self.OnClick_send)
wx.EVT_BUTTON(self, self.mail_edit_button.GetId(), self.OnClick_edit)
self.Centre( wx.BOTH )
self.Show(True)
app.MainLoop()
def OnClick_send(self, event):
self.to = self.to_textCtrl.GetValue()
self.cc = self.cc_textCtrl.GetValue()
self.subject = self.subject_textCtrl.GetValue()
self.message_boby = self.mail_textCtrl.GetValue()
r_value = self.message_boby
self.Destroy()
return r_value
def OnClick_edit(self, event):
self.to_textCtrl.Enable(True)
self.cc_textCtrl.Enable(True)
self.subject_textCtrl.Enable(True)
self.mail_textCtrl.Enable(True)
return_values = Email_template(None, "tomail@mymail.com", "cc_copy@mymail.com", "message subject", "mail")
print return_values
it showing below error message:
wxPython wrapper for DELETED Email_template object! (The C++ object no longer exists.)
but i need to print message_body updated content from gui.
Thanks.
回答1:
First, I have changed your sizers. I have replaced them with one GridBagSizer
which is very powerful. I have also deleted most of the widget size parameters as sizer is now going to handle widget sizes based on window size. I have also removed a lot of parameters from your wx calls, as those are default. By removing default optional parameters, the code is more readable. You mostly do not need wx.ID_ANY
, wx.DefaultSize
, wx.DefaultPosition
or wx.EmptyString
etc. in wxPython
as you would in wxWidgets
.
Second, the way you have programmed your app is weird. I think you want either of the two:
1) Create an GUI application which has a window, allows you to edit, does something as you press Send. It also closes itself when you press Send in your case, so maybe that is not what you are after...
import wx
class EmailTemplate(wx.Frame):
def __init__(self, to, cc, subject, message_body):
wx.Frame.__init__(self, None, size=(650, 500))
self.panel = wx.Panel(self)
self.panel.SetBackgroundColour(wx.SystemSettings.GetColour(wx.SYS_COLOUR_INFOBK))
self.sizer = wx.GridBagSizer(5, 5)
self.sizer.AddGrowableCol(3)
self.sizer.AddGrowableRow(5)
# Add spacers. Not the best, but avoids another sizer for border
self.sizer.Add((0, 0), pos=(0, 4))
self.sizer.Add((0, 0), pos=(6, 0))
self.mail_send_button = wx.Button(self.panel, label="Send")
self.mail_send_button.Bind(wx.EVT_BUTTON, self.OnClick_send)
self.sizer.Add(self.mail_send_button, pos=(1, 1), span=(2, 1), flag=wx.EXPAND)
self.mail_edit_button = wx.Button(self.panel, label="Edit")
self.mail_edit_button.Bind(wx.EVT_BUTTON, self.OnClick_edit)
self.sizer.Add(self.mail_edit_button, pos=(3, 1), span=(2, 1), flag=wx.EXPAND)
self.from_staticText = wx.StaticText(self.panel, label="From:")
self.sizer.Add(self.from_staticText, pos=(1, 2), flag=wx.ALIGN_CENTER_VERTICAL)
self.from_textCtrl = wx.TextCtrl(self.panel, value="from_mail@mymail.com")
self.sizer.Add(self.from_textCtrl, pos=(1, 3), flag=wx.EXPAND)
self.to_staticText = wx.StaticText(self.panel, label="To:")
self.sizer.Add(self.to_staticText, pos=(2, 2), flag=wx.ALIGN_CENTER_VERTICAL)
self.to_textCtrl = wx.TextCtrl(self.panel, value=to)
self.sizer.Add(self.to_textCtrl, pos=(2, 3), flag=wx.EXPAND)
self.cc_staticText = wx.StaticText(self.panel, label="CC:")
self.sizer.Add(self.cc_staticText, pos=(3, 2), flag=wx.ALIGN_CENTER_VERTICAL)
self.cc_textCtrl = wx.TextCtrl(self.panel, value=cc)
self.sizer.Add(self.cc_textCtrl, pos=(3, 3), flag=wx.EXPAND)
self.subject_staticText = wx.StaticText(self.panel, label="Subject:")
self.sizer.Add(self.subject_staticText, pos=(4, 2), flag=wx.ALIGN_CENTER_VERTICAL)
self.subject_textCtrl = wx.TextCtrl(self.panel, value=subject)
self.sizer.Add(self.subject_textCtrl, pos=(4, 3), flag=wx.EXPAND)
self.mail_textCtrl = wx.TextCtrl(self.panel, value=message_body, style=wx.TE_MULTILINE)
self.sizer.Add(self.mail_textCtrl, pos=(5, 1), span=(1, 3), flag=wx.EXPAND)
self.panel.SetSizerAndFit(self.sizer)
self.to_textCtrl.Disable()
self.cc_textCtrl.Disable()
self.subject_textCtrl.Disable()
self.mail_textCtrl.Disable()
self.Show()
def OnClick_send(self, event):
self.DoSomethingWithEmail(self.to_textCtrl.GetValue(),
self.cc_textCtrl.GetValue(),
self.subject_textCtrl.GetValue(),
self.mail_textCtrl.GetValue())
self.Close()
def OnClick_edit(self, event):
self.to_textCtrl.Enable(True)
self.cc_textCtrl.Enable(True)
self.subject_textCtrl.Enable(True)
self.mail_textCtrl.Enable(True)
def DoSomethingWithEmail(self, to, cc, subject, text):
# Maybe send here?
print to, cc, subject, text
app = wx.App(False)
window = EmailTemplate("tomail@mymail.com", "cc_copy@mymail.com", "message subject", "mail")
app.MainLoop()
2) Create just a Dialog, show the dialog, have it closed by the user (using Send) and follow with your Python script without having a real GUI application.
import wx
class EmailTemplate(wx.Dialog):
def __init__(self, to, cc, subject, message_body):
wx.Dialog.__init__(self, None, size=(650, 500))
self.panel = wx.Panel(self)
self.panel.SetBackgroundColour(wx.SystemSettings.GetColour(wx.SYS_COLOUR_INFOBK))
self.main_sizer = wx.BoxSizer()
self.sizer = wx.GridBagSizer(5, 5)
self.sizer.AddGrowableCol(3)
self.sizer.AddGrowableRow(5)
# Add spacers. Not the best, but avoids another sizer for border
self.sizer.Add((0, 0), pos=(0, 4))
self.sizer.Add((0, 0), pos=(6, 0))
self.mail_send_button = wx.Button(self.panel, label="Send")
self.mail_send_button.Bind(wx.EVT_BUTTON, self.OnClick_send)
self.sizer.Add(self.mail_send_button, pos=(1, 1), span=(2, 1), flag=wx.EXPAND)
self.mail_edit_button = wx.Button(self.panel, label="Edit")
self.mail_edit_button.Bind(wx.EVT_BUTTON, self.OnClick_edit)
self.sizer.Add(self.mail_edit_button, pos=(3, 1), span=(2, 1), flag=wx.EXPAND)
self.from_staticText = wx.StaticText(self.panel, label="From:")
self.sizer.Add(self.from_staticText, pos=(1, 2), flag=wx.ALIGN_CENTER_VERTICAL)
self.from_textCtrl = wx.TextCtrl(self.panel, value="from_mail@mymail.com")
self.sizer.Add(self.from_textCtrl, pos=(1, 3), flag=wx.EXPAND)
self.to_staticText = wx.StaticText(self.panel, label="To:")
self.sizer.Add(self.to_staticText, pos=(2, 2), flag=wx.ALIGN_CENTER_VERTICAL)
self.to_textCtrl = wx.TextCtrl(self.panel, value=to)
self.sizer.Add(self.to_textCtrl, pos=(2, 3), flag=wx.EXPAND)
self.cc_staticText = wx.StaticText(self.panel, label="CC:")
self.sizer.Add(self.cc_staticText, pos=(3, 2), flag=wx.ALIGN_CENTER_VERTICAL)
self.cc_textCtrl = wx.TextCtrl(self.panel, value=cc)
self.sizer.Add(self.cc_textCtrl, pos=(3, 3), flag=wx.EXPAND)
self.subject_staticText = wx.StaticText(self.panel, label="Subject:")
self.sizer.Add(self.subject_staticText, pos=(4, 2), flag=wx.ALIGN_CENTER_VERTICAL)
self.subject_textCtrl = wx.TextCtrl(self.panel, value=subject)
self.sizer.Add(self.subject_textCtrl, pos=(4, 3), flag=wx.EXPAND)
self.mail_textCtrl = wx.TextCtrl(self.panel, value=message_body, style=wx.TE_MULTILINE)
self.sizer.Add(self.mail_textCtrl, pos=(5, 1), span=(1, 3), flag=wx.EXPAND)
self.panel.SetSizer(self.sizer)
self.main_sizer.Add(self.panel, 1, flag=wx.EXPAND)
self.SetSizer(self.main_sizer)
self.to_textCtrl.Disable()
self.cc_textCtrl.Disable()
self.subject_textCtrl.Disable()
self.mail_textCtrl.Disable()
def OnClick_send(self, event):
self.to = self.to_textCtrl.GetValue()
self.cc = self.cc_textCtrl.GetValue()
self.subject = self.subject_textCtrl.GetValue()
self.body = self.mail_textCtrl.GetValue()
self.EndModal(wx.ID_OK)
def OnClick_edit(self, event):
self.to_textCtrl.Enable(True)
self.cc_textCtrl.Enable(True)
self.subject_textCtrl.Enable(True)
self.mail_textCtrl.Enable(True)
def GetValuesAsDict(self):
d = {"to": self.to,
"cc": self.cc,
"subject": self.subject,
"body": self.body}
return d
app = wx.App(False)
dialog = EmailTemplate("tomail@mymail.com", "cc_copy@mymail.com", "message subject", "mail")
result = dialog.ShowModal()
if result == wx.ID_OK:
# Maybe send here instead of print?
print dialog.GetValuesAsDict()
Note the differences of how the code is composed. The difference may be subtle in your case, but will be more significant if you decide to build something bigger. It is also idiomatic way to use wxPython, so other programmers will find it easier to understand your code.
来源:https://stackoverflow.com/questions/20674937/return-value-from-wxpython-main-frame