Руководство по компоновке кода для нескольких кадров в wxpython - PullRequest
1 голос
/ 01 июня 2019

РЕДАКТИРОВАНИЕ ~ Теперь с кодом.

Я новичок в кодировании и пытаюсь получить переменные, вводимые в вывод "frameA" в "frameB". Мой вопрос заключается в том, как написать код, чтобы можно было использовать переменную, введенную в FrameA (и обновлять ее при вводе пользователем - нажатием кнопки или отменой выбора textctrl и т. Д.) В frameB?

Я использую wxpython и использую Wx Builder в качестве руководства, но при написании реального кода пользовательского интерфейса я сам помог понять, что происходит под ним. Я пробовал class -> def -> Frame UI, и кадры организованы так, как я хочу, отображать и скрывать, как я хочу, а переменные, которые я хочу, можно распечатывать при нажатии кнопок ввода / нажатия и т. Д. В этом кадре, но они недоступны из за пределами этого кадра, хотя я возвращаю необходимые переменные.

В этом примере я хочу взять то, что написано в textctrl frameA, и сохранить его как переменную, доступную (и обновленную) для других классов, в данном случае 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' может (?) обновить «глобальный» var, но это не обновляется в frameB. Что мне не хватает? Я пытался избегать использования глобальных переменных, так как слышал, что это плохая привычка рано начинать ...

Спасибо, Закат

1 Ответ

1 голос
/ 03 июня 2019

Если вы хотите, чтобы значение var было доступно для всех классов, вам нужно добавить строку global var в метод InputUpdate() в Class FrameA перед тем, как присвоить новое значение 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()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...