我具有以下类层次结构:
wx.Frame派生类;在该框架内,我有一个拆分器窗口,以及一个链接到该拆分器窗口的基于wx.Panel的类。在面板中,我有一个按钮。我将事件处理程序绑定到按钮以执行一些操作。问题在于,大多数动作应该在框架类内完成。因此,我必须以某种方式从按钮甚至处理程序的框架类中调用方法。我怎样才能做到这一点?代码的相关部分在下面。
欢呼声
class EPSPanel(wx.Panel):
def __init__(self, parent):
super().__init__(parent)
lbl_SGCR = wx.StaticText(self, label="SGCR", pos=(20, 20))
self.ent_SGCR = wx.TextCtrl(self, value="", pos=(100,20), size=(200,-1))
lbl_SWCR = wx.StaticText(self, label="SWCR", pos=(20, 60))
self.ent_SWCR = wx.TextCtrl(self, value="", pos=(100,60), size=(200,-1))
lbl_SWU = wx.StaticText(self, label="SWU", pos=(20, 100))
self.ent_SWU = wx.TextCtrl(self, value="", pos=(100,100), size=(200,-1))
lbl_SGU = wx.StaticText(self, label="SGU", pos=(20, 140))
self.ent_SGU = wx.TextCtrl(self, value="", pos=(100,140), size=(200,-1))
lbl_SWL = wx.StaticText(self, label="SWL", pos=(20, 180))
self.ent_SWL = wx.TextCtrl(self, value="", pos=(100,180), size=(200,-1))
lbl_SGL = wx.StaticText(self, label="SGL", pos=(20, 220))
self.ent_SGL = wx.TextCtrl(self, value="", pos=(100,220), size=(200,-1))
calc_button = wx.Button(self, label="Calculate", pos=(110,260))
calc_button.Bind(wx.EVT_BUTTON, self.on_btn)
def on_btn(self, event):
self.set_SGCR = float(self.ent_SGCR.GetValue())
self.set_SWCR = float(self.ent_SWCR.GetValue())
self.set_SGU = float(self.ent_SGU.GetValue())
self.set_SWU = float(self.ent_SWU.GetValue())
# these four values in this method I need to pass to the KrFrame class
# instance to process in one of its methods. I also need somehow
# let the frame class know that that button was pressed. How can I do it?
class KrFrame(wx.Frame):
def __init__(self):
super().__init__(parent=None,
title='Gas Relative Permeability Editor', size=(900, 800))
self.sp = wx.SplitterWindow(self)
self.rightSplitter = wx.SplitterWindow(self.sp) #Another splitter to split right panel into two vertical ones
self.leftSplitter = wx.SplitterWindow(self.sp)
self.panel01 = KrPanel(self.leftSplitter)
self.panel02 = PlotPanel(self.rightSplitter)
self.panel03 = EPSPanel(self.rightSplitter) #Third panel for scaled end point entry
self.panel04 = KrPanel(self.leftSplitter)
self.rightSplitter.SplitHorizontally(self.panel02, self.panel03, 400) #Splitting right panel into two horizontally
self.leftSplitter.SplitHorizontally(self.panel01, self.panel04, 400)
self.sp.SplitVertically(self.leftSplitter, self.rightSplitter, 450)
self.create_menu()
self.Show()
if __name__ == '__main__':
app = wx.App(False)
frame = KrFrame()
app.MainLoop()
del app
您可以调用框架内定义的函数,尽管要对数据做一些有用的工作,但由于在框架内的拆分器窗口内定义了拆分器窗口,因此变得更加困难。供以后参考,最好提供一个运行版本的示例代码。许多可以回答这个问题的人都不想重新哈希代码以使其运行。
这应该给您带来深思的地方。
import wx
class EPSPanel(wx.Panel):
def __init__(self, parent):
super().__init__(parent)
#track the real parent for updating purposes
#
self.parent = parent.GrandParent
#
lbl_SGCR = wx.StaticText(self, label="SGCR", pos=(20, 20))
self.ent_SGCR = wx.TextCtrl(self, value="", pos=(100,20), size=(200,-1))
lbl_SWCR = wx.StaticText(self, label="SWCR", pos=(20, 60))
self.ent_SWCR = wx.TextCtrl(self, value="", pos=(100,60), size=(200,-1))
lbl_SWU = wx.StaticText(self, label="SWU", pos=(20, 100))
self.ent_SWU = wx.TextCtrl(self, value="", pos=(100,100), size=(200,-1))
lbl_SGU = wx.StaticText(self, label="SGU", pos=(20, 140))
self.ent_SGU = wx.TextCtrl(self, value="", pos=(100,140), size=(200,-1))
lbl_SWL = wx.StaticText(self, label="SWL", pos=(20, 180))
self.ent_SWL = wx.TextCtrl(self, value="", pos=(100,180), size=(200,-1))
lbl_SGL = wx.StaticText(self, label="SGL", pos=(20, 220))
self.ent_SGL = wx.TextCtrl(self, value="", pos=(100,220), size=(200,-1))
calc_button = wx.Button(self, label="Calculate", pos=(110,260))
calc_button.Bind(wx.EVT_BUTTON, self.on_btn)
def on_btn(self, event):
self.set_SGCR = float(self.ent_SGCR.GetValue())
self.set_SWCR = float(self.ent_SWCR.GetValue())
self.set_SGU = float(self.ent_SGU.GetValue())
self.set_SWU = float(self.ent_SWU.GetValue())
# these four values in this method I need to pass to the KrFrame class
# instance to process in one of its methods. I also need somehow
# let the frame class know that that button was pressed. How can I do it?
KrFrame.mycalculation(self.parent,self.set_SGCR,self.set_SWCR,self.set_SGU,self.set_SWU)
class KrFrame(wx.Frame):
def __init__(self):
super().__init__(parent=None,
title='Gas Relative Permeability Editor', size=(900, 800))
self.sp = wx.SplitterWindow(self)
self.rightSplitter = wx.SplitterWindow(self.sp) #Another splitter to split right panel into two vertical ones
self.leftSplitter = wx.SplitterWindow(self.sp)
self.panel01 = wx.Panel(self.leftSplitter)
self.Total = wx.TextCtrl(self.panel01)
self.panel02 = wx.Panel(self.rightSplitter)
self.panel03 = EPSPanel(self.rightSplitter) #Third panel for scaled end point entry
self.panel04 = wx.Panel(self.leftSplitter)
self.rightSplitter.SplitHorizontally(self.panel02, self.panel03, 400) #Splitting right panel into two horizontally
self.leftSplitter.SplitHorizontally(self.panel01, self.panel04, 400)
self.sp.SplitVertically(self.leftSplitter, self.rightSplitter, 450)
# self.create_menu()
self.Total.SetValue("00000.00")
self.Show()
def mycalculation(parent,SGCR=0,SWCR=0,SGU=0,SWU=0):
print ("Total of values:",SGCR,SWCR,SGU,SWU,"=",SGCR+SWCR+SGU+SWU)
parent.Total.SetValue(str(SGCR+SWCR+SGU+SWU))
if __name__ == '__main__':
app = wx.App(False)
frame = KrFrame()
app.MainLoop()
感谢罗尔夫。共享代码的问题在于,它已经在许多模块上蓬勃发展,而共享所有模块将导致数米的滚动。我发现了以下解决方法。我的理解是,事件在子窗口小部件的所有父类之间传播。因此,如果单击按钮,wxFrame也将获取事件。因此,我正在绑定到WxFrame的构造函数下的按钮类的实例。在绑定中,我正在定义事件处理逻辑。这似乎有效:
class KrFrame(wx.Frame):
def __init__(self):
super().__init__(parent=None,
title='Gas Relative Permeability Editor', size=(900, 800))
self.sp = wx.SplitterWindow(self)
self.rightSplitter = wx.SplitterWindow(self.sp) #Another splitter to split right panel into two vertical ones
self.leftSplitter = wx.SplitterWindow(self.sp)
self.panel01 = KrPanel(self.leftSplitter)
self.panel02 = PlotPanel(self.rightSplitter)
self.panel03 = EPSPanel(self.rightSplitter) #Third panel for scaled end point entry
self.panel03.calc_button.Bind(wx.EVT_BUTTON, self.on_btn)
self.panel04 = KrPanel(self.leftSplitter)
self.rightSplitter.SplitHorizontally(self.panel02, self.panel03, 400) #Splitting right panel into two horizontally
self.leftSplitter.SplitHorizontally(self.panel01, self.panel04, 400)
self.sp.SplitVertically(self.leftSplitter, self.rightSplitter, 450)
self.create_menu()
self.Show()
def on_btn(self, event):
self.set_SGCR = float(self.panel03.ent_SGCR.GetValue())
self.set_SWCR = float(self.panel03.ent_SWCR.GetValue())
self.set_SGU = float(self.panel03.ent_SGU.GetValue())
self.set_SWU = float(self.panel03.ent_SWU.GetValue())
print(self.set_SGCR, self.set_SWCR, self.set_SGU, self.set_SWU)