wxpython 如何更改其他面板中的小部件的值

wxpython How to change the values of widgets in other panel

我的frame被分成了三个panel,PanelTwo里面有一个TextCtrl,PanelThree里面也有一个TextCtrl,当我在PanelTwo的TextCtrl里面输入东西的时候,我需要修改PanelThree里面TextCtrl的值, 怎么做?

# -*- coding: utf-8 -*-
import wx
import sys


class PanelOne(wx.Panel):
    """"""
 
    #----------------------------------------------------------------------
    def __init__(self, parent):
        """Constructor"""
        wx.Panel.__init__(self, parent)
        self.SetBackgroundColour("blue")
        font = wx.Font(12, wx.DECORATIVE, wx.NORMAL, wx.BOLD)
        button1 = wx.Button(self, -1, label='Button1')
        button2 = wx.Button(self, -1, label='Button2')
        button1.SetFont(font)
        button2.SetFont(font)
        

        vbox = wx.BoxSizer(wx.VERTICAL)
        vbox.Add(button1, 1, wx.EXPAND)
        vbox.Add(button2, 1, wx.EXPAND)
        self.SetSizer(vbox)
        
class PanelTwo(wx.Panel):
    """"""
    
    #----------------------------------------------------------------------
    def __init__(self, parent):
        """Constructor"""
        wx.Panel.__init__(self, parent)
        textctrl = wx.TextCtrl(self, -1, pos=(200,120), style=wx.TE_PROCESS_ENTER|wx.CENTER)    
        textctrl.Bind(wx.EVT_KEY_DOWN, self.OnEnter)
        
    def OnEnter(self, event):
        keycode = event.GetKeyCode()
        if keycode == wx.WXK_RETURN or keycode == wx.WXK_NUMPAD_ENTER:
            """Here, I want to Print some message in PanelThree textctrl """
        event.Skip()

class PanelThree(wx.Panel):
    """"""
 
    #----------------------------------------------------------------------
    def __init__(self, parent):
        """Constructor"""
        wx.Panel.__init__(self, parent)
        self.SetBackgroundColour("white")
        
        text = wx.TextCtrl(self, -1, 
                            style = wx.TE_MULTILINE|wx.TE_READONLY|
                            wx.HSCROLL)
        vbox = wx.BoxSizer(wx.VERTICAL)
        vbox.Add(text, 1, wx.EXPAND)
        self.SetSizer(vbox)
        
 
########################################################################
class MainPanel(wx.Panel):
    """"""
 
    #----------------------------------------------------------------------
    def __init__(self, parent):
        """Constructor"""
        wx.Panel.__init__(self, parent)
 
        topSplitter = wx.SplitterWindow(self, size=(800,600))
        vSplitter = wx.SplitterWindow(topSplitter)
 
        self.panelOne = PanelOne(vSplitter)
        self.panelTwo = PanelTwo(vSplitter)
        self.panelThree = PanelThree(topSplitter)
        
        vSplitter.SplitVertically(self.panelOne, self.panelTwo)
        vSplitter.SetSashGravity(0.3)

        topSplitter.SplitHorizontally(vSplitter, self.panelThree)
        topSplitter.SetSashGravity(0.5)
 
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(topSplitter, 1, wx.EXPAND)
        
        

########################################################################
class MainFrame(wx.Frame):
    """"""
 
    #----------------------------------------------------------------------
    def __init__(self):
        """Constructor"""
        wx.Frame.__init__(self, None, title='my program',
                          size=(800,600))
        panel = MainPanel(self)
        self.Show()
 
#----------------------------------------------------------------------
if __name__ == "__main__":
    app = wx.App(False)
    frame = MainFrame()
    app.MainLoop()

我不确定这是否是最好的方法。无论如何,我已将您的代码修改如下:

# -*- coding: utf-8 -*-
import wx
import sys


class PanelOne(wx.Panel):
    """"""

    #----------------------------------------------------------------------
    def __init__(self, parent):
        """Constructor"""
        wx.Panel.__init__(self, parent)
        self.SetBackgroundColour("blue")
        font = wx.Font(12, wx.DECORATIVE, wx.NORMAL, wx.BOLD)
        button1 = wx.Button(self, -1, label='Button1')
        button2 = wx.Button(self, -1, label='Button2')
        button1.SetFont(font)
        button2.SetFont(font)


        vbox = wx.BoxSizer(wx.VERTICAL)
        vbox.Add(button1, 1, wx.EXPAND)
        vbox.Add(button2, 1, wx.EXPAND)
        self.SetSizer(vbox)

class PanelTwo(wx.Panel):
    """"""

    #----------------------------------------------------------------------
    def __init__(self, parent):
        """Constructor"""
        wx.Panel.__init__(self, parent)
        self.textctrl = wx.TextCtrl(self, -1, pos=(200,120), style=wx.TE_PROCESS_ENTER|wx.CENTER)    



class PanelThree(wx.Panel):
    """"""

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

        self.text = wx.TextCtrl(self, -1, 
                            style = wx.TE_MULTILINE|wx.TE_READONLY|
                            wx.HSCROLL)
        vbox = wx.BoxSizer(wx.VERTICAL)
        vbox.Add(self.text, 1, wx.EXPAND)
        self.SetSizer(vbox)


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

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

        topSplitter = wx.SplitterWindow(self, size=(800,600))
        vSplitter = wx.SplitterWindow(topSplitter)

        self.panelOne = PanelOne(vSplitter)
        self.panelTwo = PanelTwo(vSplitter)
        self.panelThree = PanelThree(topSplitter)

        self.panelTwo.textctrl.Bind(wx.EVT_KEY_DOWN, self.OnEnter)

        vSplitter.SplitVertically(self.panelOne, self.panelTwo)
        vSplitter.SetSashGravity(0.3)

        topSplitter.SplitHorizontally(vSplitter, self.panelThree)
        topSplitter.SetSashGravity(0.5)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(topSplitter, 1, wx.EXPAND)

    def OnEnter(self, event):
        keycode = event.GetKeyCode()
        if keycode == wx.WXK_RETURN or keycode == wx.WXK_NUMPAD_ENTER:
            """Here, I want to Print some message in PanelThree textctrl """
            self.panelThree.text.SetValue("ENTER PRESSED")
        else:
            self.panelThree.text.SetValue("")
        event.Skip()



########################################################################
class MainFrame(wx.Frame):
    """"""

    #----------------------------------------------------------------------
    def __init__(self):
        """Constructor"""
        wx.Frame.__init__(self, None, title='my program',
                          size=(800,600))
        panel = MainPanel(self)
        self.Show()

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

编辑:

但是,参考 GreenAsJade's answer to this question,使用 pubsub 似乎是一种更简洁的实现方式。

# -*- coding: utf-8 -*-
import wx
import sys
from wx.lib.pubsub import pub

class PanelOne(wx.Panel):
    """"""

    #----------------------------------------------------------------------
    def __init__(self, parent):
        """Constructor"""
        wx.Panel.__init__(self, parent)
        self.SetBackgroundColour("blue")
        font = wx.Font(12, wx.DECORATIVE, wx.NORMAL, wx.BOLD)
        button1 = wx.Button(self, -1, label='Button1')
        button2 = wx.Button(self, -1, label='Button2')
        button1.SetFont(font)
        button2.SetFont(font)


        vbox = wx.BoxSizer(wx.VERTICAL)
        vbox.Add(button1, 1, wx.EXPAND)
        vbox.Add(button2, 1, wx.EXPAND)
        self.SetSizer(vbox)

class PanelTwo(wx.Panel):
    """"""

    #----------------------------------------------------------------------
    def __init__(self, parent):
        """Constructor"""
        wx.Panel.__init__(self, parent)
        textctrl = wx.TextCtrl(self, -1, pos=(200,120), style=wx.TE_PROCESS_ENTER|wx.CENTER)    
        textctrl.Bind(wx.EVT_KEY_DOWN, self.OnEnter)

    def OnEnter(self, event):
        keycode = event.GetKeyCode()
        pub.sendMessage("CHANGE_TEXT",value="")
        if keycode == wx.WXK_RETURN or keycode == wx.WXK_NUMPAD_ENTER:
            """Here, I want to Print some message in PanelThree textctrl """
            pub.sendMessage("CHANGE_TEXT", value = "Enter Pressed")
        event.Skip()

class PanelThree(wx.Panel):
    """"""

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

        self.text = wx.TextCtrl(self, -1, 
                            style = wx.TE_MULTILINE|wx.TE_READONLY|
                            wx.HSCROLL)
        vbox = wx.BoxSizer(wx.VERTICAL)
        vbox.Add(self.text, 1, wx.EXPAND)
        self.SetSizer(vbox)
        pub.subscribe(self.PrintMessage, "CHANGE_TEXT")

    def PrintMessage(self, value):
        self.text.SetValue(value)



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

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

        topSplitter = wx.SplitterWindow(self, size=(800,600))
        vSplitter = wx.SplitterWindow(topSplitter)

        self.panelOne = PanelOne(vSplitter)
        self.panelTwo = PanelTwo(vSplitter)
        self.panelThree = PanelThree(topSplitter)

        vSplitter.SplitVertically(self.panelOne, self.panelTwo)
        vSplitter.SetSashGravity(0.3)

        topSplitter.SplitHorizontally(vSplitter, self.panelThree)
        topSplitter.SetSashGravity(0.5)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(topSplitter, 1, wx.EXPAND)



########################################################################
class MainFrame(wx.Frame):
    """"""

    #----------------------------------------------------------------------
    def __init__(self):
        """Constructor"""
        wx.Frame.__init__(self, None, title='my program',
                          size=(800,600))
        panel = MainPanel(self)
        self.Show()

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