如何在父窗口中从子窗口访问窗口小部件?

时间:2015-08-16 13:20:18

标签: python wxpython

我有一个带有面板(笔记本)和组合框的父类,如下所示:

class A(wx.aui.AuiMDIChildFrame): 
    def __init__(self,parent):
        self.panel_1 = wx.Panel(self, -1)
        self.NB = wx.Notebook(self.panel_1, -1, style=0)
        self.NB_A= WindowFirst(self.NB)

        self.ComboA= wx.ComboBox(self.panel_1, 500, 'Phase', (50, 150), (160,-1), phasesList, wx.CB_DROPDOWN)

并在另一个py文件中:

class WindowFirst(GeneralPanel):
    def __init__(self,parent):
        how do I access ComboA from here?

这不是我的完整代码......只是想要与此问题相关。

如何从comboA访问WindowFirst?我需要能够将ComboA的值设置为WindowFirst

我可以从A访问WindowFirst,但不是相反。

有什么建议吗?

2 个答案:

答案 0 :(得分:0)

只要您尝试从WindowFirst访问ComboA,就无法完成此操作。 init ()。在创建NB_A时调用WindowFirst的构造函数,此时尚未创建ComboA。因此,无论您如何尝试访问ComboA,都不可能,因为它不存在

但是,如果您想从另一种WindowFirst方法访问ComboA,可以这样做。你有NB_A作为NB的孩子,NB作为panel_1的孩子,panel_1作为A的孩子,作为A的孩子的ComboA。您只需确保ComboA存在,然后再尝试访问它。就像这样。

def anotherFunction():
    #how do I access ComboA from here?
    nb = self.GetParent()
    panel_1 = nb.GetParent()
    a = panel_1.GetParent()
    try:
        #try to access ComboA and do what you gotta do
        a.ComboA.doSomething()
    except:
        #something went wrong (like ComboA doesn't exist yet)
        print "ComboA doesn't exist yet"

或简洁

def anotherFunction():
    #how do I access ComboA from here?
    try:
        self.GetParent().GetGrandParent().ComboA.doSomething()
    except:
        print "ComboA doesn't exist yet"

答案 1 :(得分:0)

在wxPython中,类之间进行通信的推荐方法是使用pubsub,它包含在wxPython中。基本上,您需要在班级A中创建一个监听器,然后从WindowFirst向其发布消息,告诉它更新。

以下是一个例子:

import random
import wx
from wx.lib.pubsub import pub

########################################################################
class TabPanel(wx.Panel):
    #----------------------------------------------------------------------
    def __init__(self, parent):
        """"""
        wx.Panel.__init__(self, parent)

        colors = ["red", "blue", "gray", "yellow", "green"]
        self.color = random.choice(colors)
        self.SetBackgroundColour(self.color)
        self.Bind(wx.EVT_LEFT_DCLICK, self.update_button)

        lbox = wx.ListBox(self, choices=colors)
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(lbox, 0, wx.ALL, 10)
        self.SetSizer(sizer)

    #----------------------------------------------------------------------
    def update_button(self, event):
        """"""
        pub.sendMessage('button_listener', message=self.color)

########################################################################
class MyPanel(wx.Panel):
    """"""

    #----------------------------------------------------------------------
    def __init__(self, parent):
        """Constructor"""
        wx.Panel.__init__(self, parent)


########################################################################
class DemoFrame(wx.Frame):
    """
    Frame that holds all other widgets
    """

    #----------------------------------------------------------------------
    def __init__(self):
        """Constructor"""
        wx.Frame.__init__(self, None, wx.ID_ANY,
                          "Notebook Tutorial",
                          size=(600,400)
                          )
        panel = MyPanel(self)
        self.tab_num = 3

        self.notebook = wx.Notebook(panel)
        tabOne = TabPanel(self.notebook)
        self.notebook.AddPage(tabOne, "Tab 1")

        tabTwo = TabPanel(self.notebook)
        self.notebook.AddPage(tabTwo, "Tab 2")

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.notebook, 1, wx.ALL|wx.EXPAND, 5)

        self.btn = wx.Button(panel, label="Get Color")
        sizer.Add(self.btn)

        panel.SetSizer(sizer)
        self.Layout()

        # create a listener
        pub.subscribe(self.change_button, 'button_listener')

        self.Show()

    #----------------------------------------------------------------------
    def change_button(self, message, arg2=None):
        """"""
        self.btn.SetLabel(message)

#----------------------------------------------------------------------
if __name__ == "__main__":
    app = wx.App(False)
    frame = DemoFrame()
    app.MainLoop()

请注意,在wxPython 2.9及更高版本中,pubsub API略有改变。如果您使用的是旧版本,那么您需要稍微更改一下代码。我有一个教程,说明较旧的API here

有关较新API的更多信息,请查看我在此处更新的文章: