我已经使用 python 有一段时间了,并且刚刚开始学习 wxPython。在创建了一些小程序之后,我很难理解如何创建可以在对话框之间共享的对象。
以下是一些代码作为示例(为长度道歉 - 我试图修剪):
import wx
class ExampleFrame(wx.Frame):
"""The main GUI"""
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title, size=(200,75))
mainSizer = wx.BoxSizer(wx.VERTICAL)
# Setup buttons
buttonSizer = wx.BoxSizer(wx.HORIZONTAL)
playerButton = wx.Button(self, wx.ID_ANY, "Player number", wx.DefaultPosition, wx.DefaultSize, 0)
buttonSizer.Add(playerButton, 1, wx.ALL | wx.EXPAND, 0)
nameButton = wx.Button(self, wx.ID_ANY, "Player name", wx.DefaultPosition, wx.DefaultSize, 0)
buttonSizer.Add(nameButton, 1, wx.ALL | wx.EXPAND, 0)
# Complete layout and add statusbar
mainSizer.Add(buttonSizer, 1, wx.EXPAND, 5)
self.SetSizer(mainSizer)
self.Layout()
# Deal with the events
playerButton.Bind(wx.EVT_BUTTON, self.playerButtonEvent)
nameButton.Bind(wx.EVT_BUTTON, self.nameButtonEvent)
self.Show(True)
return
def playerButtonEvent(self, event):
"""Displays the number of game players"""
playerDialog = PlayerDialogWindow(None, -1, "Player")
playerDialogResult = playerDialog.ShowModal()
playerDialog.Destroy()
return
def nameButtonEvent(self, event):
"""Displays the names of game players"""
nameDialog = NameDialogWindow(None, -1, "Name")
nameDialogResult = nameDialog.ShowModal()
nameDialog.Destroy()
return
class PlayerDialogWindow(wx.Dialog):
"""Displays the player number"""
def __init__(self, parent, id, title):
wx.Dialog.__init__(self, parent, id, title, size=(200,120))
# Setup layout items
self.SetAutoLayout(True)
mainSizer = wx.BoxSizer(wx.VERTICAL)
dialogPanel = wx.Panel(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL)
dialogSizer = wx.BoxSizer(wx.VERTICAL)
# Display player number
playerNumber = "Player number is %i" % gamePlayer.number
newLabel = wx.StaticText(dialogPanel, wx.ID_ANY, playerNumber, wx.DefaultPosition, wx.DefaultSize, 0)
dialogSizer.Add(newLabel, 0, wx.ALL | wx.EXPAND, 5)
# Setup buttons
buttonSizer = wx.StdDialogButtonSizer()
okButton = wx.Button(dialogPanel, wx.ID_OK)
buttonSizer.AddButton(okButton)
buttonSizer.Realize()
dialogSizer.Add(buttonSizer, 1, wx.EXPAND, 5)
# Complete layout
dialogPanel.SetSizer(dialogSizer)
dialogPanel.Layout()
dialogSizer.Fit(dialogPanel)
mainSizer.Add(dialogPanel, 1, wx.ALL | wx.EXPAND, 5)
self.SetSizer(mainSizer)
self.Layout()
# Deal with the button events
okButton.Bind(wx.EVT_BUTTON, self.okClick)
return
def okClick(self, event):
"""Deals with the user clicking the ok button"""
self.EndModal(wx.ID_OK)
return
class NameDialogWindow(wx.Dialog):
"""Displays the player name"""
def __init__(self, parent, id, title):
wx.Dialog.__init__(self, parent, id, title, size=(200,120))
# Setup layout items
self.SetAutoLayout(True)
mainSizer = wx.BoxSizer(wx.VERTICAL)
dialogPanel = wx.Panel(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL)
dialogSizer = wx.BoxSizer(wx.VERTICAL)
# Display player number
playerNumber = "Player name is %s" % gamePlayer.name
newLabel = wx.StaticText(dialogPanel, wx.ID_ANY, playerNumber, wx.DefaultPosition, wx.DefaultSize, 0)
dialogSizer.Add(newLabel, 0, wx.ALL | wx.EXPAND, 5)
# Setup buttons
buttonSizer = wx.StdDialogButtonSizer()
okButton = wx.Button(dialogPanel, wx.ID_OK)
buttonSizer.AddButton(okButton)
buttonSizer.Realize()
dialogSizer.Add(buttonSizer, 1, wx.EXPAND, 5)
# Complete layout
dialogPanel.SetSizer(dialogSizer)
dialogPanel.Layout()
dialogSizer.Fit(dialogPanel)
mainSizer.Add(dialogPanel, 1, wx.ALL | wx.EXPAND, 5)
self.SetSizer(mainSizer)
self.Layout()
# Deal with the button events
okButton.Bind(wx.EVT_BUTTON, self.okClick)
return
def okClick(self, event):
"""Deals with the user clicking the ok button"""
self.EndModal(wx.ID_OK)
return
class Player(object):
"""A game player"""
def __init__(self, number, name):
self.number = number
self.name = name
return
def main():
# Start GUI
global gamePlayer
gamePlayer = Player(1, "John Smith")
app = wx.App(redirect=False)
frame = ExampleFrame(None, -1, "Example frame")
frame.Show(True)
app.MainLoop()
return 0
if __name__ == '__main__':
main()
所以,我希望这两个对话框都能访问 gamePlayer 对象。目前,我能想到的唯一方法是将 gamePlayer 对象创建为全局对象,但这些通常是不受欢迎的——有没有更好的方法来做到这一点?
这个问题中有一种在事件绑定中传递对象的方法,但感觉不太对劲。
学习实现 MVC 模式是前进的方向吗?
谢谢。