wxpython中多个框架的代码布局指南

Code Layout guide for multiple frames in wxpython

已编辑~现在有代码。

我是编码新手,正在努力将变量输入“frameA”输出到“frameB”。我的问题是,代码的布局应该如何编写,以便输入到 FrameA 的变量在 frameB 中可用(并在用户输入时刷新 - 单击按钮或取消选择 textctrl 等)?

我正在使用 wxpython,并使用 Wx builder 作为指南,但是编写实际的 UI 代码使用我自己来帮助理解底层发生的事情。我试过 class -> def -> frame UI 并且框架按我想要的方式组织,按我想要的方式显示和隐藏,我想要的变量可以在 entry/button 点击时打印等在该框架内,但无法从该框架外部访问,即使我正在返回所需的变量。

在这个例子中,我想获取 frameA 的 textctrl 中写入的内容,并将其保存为其他 classes 可访问(和更新)的变量,在本例中为 FrameB。

import wx

var = "This Should change to whatever is typed in FrameA"

class FrameA ( wx.Frame ):

    def __init__( self, parent ):
        wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = wx.EmptyString, pos = (0,0), size = wx.Size( 500,300 ), style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL ) 
        bSizer1 = wx.BoxSizer( wx.HORIZONTAL )
        self.INPUT = wx.TextCtrl( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 )
        bSizer1.Add( self.INPUT, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 )
        self.SetSizer( bSizer1 )
        self.INPUT.Bind( wx.EVT_TEXT, self.InputUpdate)

    def InputUpdate(self, Evt):
        var = self.INPUT.GetValue()
        #print (var)
        return var

class FrameB ( wx.Frame ):

    def __init__( self, parent ):
        wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = wx.EmptyString, pos = (100,100), size = wx.Size( 500,300 ), style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL )
        bSizer2 = wx.BoxSizer( wx.HORIZONTAL )
        self.OUTPUT = wx.StaticText( self, wx.ID_ANY, var, wx.DefaultPosition, wx.DefaultSize, 0 )
        bSizer2.Add( self.OUTPUT, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5 )
        self.SetSizer( bSizer2 )

if __name__ == '__main__':
    app = wx.App()
    frmA = FrameA(None)
    frmB = FrameB(None)
    frmA.Centre()
    frmB.Centre()
    frmA.Show()
    frmB.Show()
app.MainLoop()

因为我还是新手,所以我可以理解每一行代码,但更大的组织对我来说仍然变得混乱。

我的理解是,编辑后 'var' 以上状态的代码只能从 frameA 中访问,并且 'return var' 可能(?)更新 'global' var,但未刷新到 frameB 中。我错过了什么?我一直在努力避免使用全局变量,因为我听说过早使用全局变量是一个坏习惯...

谢谢,日落

如果您希望所有 类 都可以访问 var 的值,那么您需要将行 global var 添加到 Class FrameA 中的方法 InputUpdate() =] 在将新值分配给 var 之前。

但是,这将使 var 仅可供此模块中的所有 类 访问。如果将代码拆分为两个文件,那么您将有两个模块,并且 var 只能在定义它的模块中访问,除非您还在另一个模块中导入定义 var 的模块。

带有相关注释的代码:

import wx

var = "This Should change to whatever is typed in FrameA"

class FrameA ( wx.Frame ):

    def __init__(self, parent):
        wx.Frame.__init__ (self, parent, id=wx.ID_ANY, title=wx.EmptyString, pos=(0,0), size=(500,300), style=wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL) 
        bSizer1 = wx.BoxSizer(wx.HORIZONTAL)
        self.INPUT = wx.TextCtrl(self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0)
        bSizer1.Add(self.INPUT, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
        self.SetSizer(bSizer1)
        self.INPUT.Bind(wx.EVT_TEXT, self.InputUpdate)

    def InputUpdate(self, Evt):
        #### You need to add the following line before assigning the new value to
        #### var in order to modify the global var variable and not the local
        #### var variable
        global var

        var = self.INPUT.GetValue()
        #print (var)
        #### The try/except block is placed to avoid having an error if the text
        #### in frameA changes but frameB does not exist anymore. The code inside
        #### the try statement changes the text in frameB in real time.
        try:
            frmB.OUTPUT.SetLabel(var)
        except Exception:
            pass

class FrameB ( wx.Frame ):

    def __init__(self, parent):
        wx.Frame.__init__ (self, parent, id=wx.ID_ANY, title=wx.EmptyString, pos=(100,100), size=(500,300), style=wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL)
        bSizer2 = wx.BoxSizer(wx.VERTICAL)
        self.OUTPUT = wx.StaticText(self, wx.ID_ANY, var, wx.DefaultPosition, wx.DefaultSize, 0)
        bSizer2.Add(self.OUTPUT, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
        #### Button to check the value of the global var variable and make sure
        #### that the code in InputUpdate actually changes the value of the global
        #### variable var
        self.button = wx.Button(self, wx.ID_ANY, label='Var Value')
        bSizer2.Add(self.button, 1, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
        self.SetSizer(bSizer2)

        self.button.Bind(wx.EVT_BUTTON, self.varValue)

    def varValue(self, event):
        #### Print the value of the global variable var
        print(var)

if __name__ == '__main__':
    app = wx.App()
    frmA = FrameA(None)
    frmB = FrameB(None)
    frmA.Centre()
    frmB.Centre()
    frmA.Show()
    frmB.Show()
app.MainLoop()