调用wx.frame类方法来处理来自框架面板上按钮的事件

问题描述 投票:0回答:2

我具有以下类层次结构:

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
python events wxpython
2个回答
0
投票

您可以调用框架内定义的函数,尽管要对数据做一些有用的工作,但由于在框架内的拆分器窗口内定义了拆分器窗口,因此变得更加困难。供以后参考,最好提供一个运行版本的示例代码。许多可以回答这个问题的人都不想重新哈希代码以使其运行。

这应该给您带来深思的地方。

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()

enter image description here


0
投票

感谢罗尔夫。共享代码的问题在于,它已经在许多模块上蓬勃发展,而共享所有模块将导致数米的滚动。我发现了以下解决方法。我的理解是,事件在子窗口小部件的所有父类之间传播。因此,如果单击按钮,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)
© www.soinside.com 2019 - 2024. All rights reserved.