pythoninheritancewxpythonwxwidgetswxglade

How do I reference a wxWidget from a separate file?


Inside of one Python file, I have a wx.Frame class called 'MyFrame,' which simply has a wx.StaticText label called 'label_1.' This file contains a subprocess (irrelevant) which runs the second file.

Inside the second Python file, I have a class that imports 'MyFrame', and contains a function called 'ChangeLabel()' which is supposed to change 'label_1' to display different text.

However, when I run the program, I get the following error:

AttributeError: type object 'MyFrame' has no attribute 'label_1'

I believe the issue has something to do with how I am importing the MyFrame class.

Below is the Code for both python files.

MainFile:

import wx
import subprocess
import sys

class MyFrame(wx.Frame):
    def __init__(self, *args, **kwds):
        # begin wxGlade: MyFrame.__init__
        kwds["style"] = kwds.get("style", 0) | wx.DEFAULT_FRAME_STYLE
        wx.Frame.__init__(self, *args, **kwds)
        self.SetSize((400, 300))
        self.SetTitle("frame")

        self.panel_1 = wx.Panel(self, wx.ID_ANY)

        sizer_1 = wx.BoxSizer(wx.VERTICAL)

        label_1 = wx.StaticText(self.panel_1, wx.ID_ANY, "This is my label")
        sizer_1.Add(label_1, 0, 0, 0)

        self.panel_1.SetSizer(sizer_1)
        
        ##Subprocess that runs "second.py"
        result = subprocess.run([sys.executable, "SecondFile.py", "arg"])

        self.Layout()
        # end wxGlade
# end of class MyFrame

class MyTestApp(wx.App):
    def OnInit(self):
        self.frame = MyFrame(None, wx.ID_ANY, "")
        self.SetTopWindow(self.frame)
        self.frame.Show()
        return True

# end of class MyTestApp

if __name__ == "__main__":
    test_app = MyTestApp(0)
    test_app.MainLoop()

SecondFile:

from MainFile import MyFrame

class SecondFile():
    def __init__(self, arg):
        self.arg = arg
    def ChangeLabel():
        ## Supposed to manipulate MyFrame's label
        MyFrame.label_1.SetLabel("New Label Text")

    ChangeLabel()

Solution

  • Following on from my comment I have produced this solution. As we all say, we don't know what you're trying to do, but this works (you need to do some work to make it a sensible app)

    module_1.py

    import wx
    import subprocess
    import sys
    
    class MainFrame(wx.Frame):
        def __init__(self, *args, **kwargs):
            super().__init__(None, *args, **kwargs)
            self.Title = 'Wx App'
    
            self.panel = MainPanel(self)
            sizer = wx.BoxSizer(wx.VERTICAL)
            sizer.Add(self.panel)
            self.SetSizer(sizer)
            self.Center()
            self.Show()
    
            result = subprocess.run([sys.executable, "module_2.py", "arg"])
            self.check_label()
    
        def check_label(self):
            with open('label_text.txt', 'r') as f_label:
                label_text = f_label.read()
            self.panel.label_1.SetLabel(label_text)
    
    
    
    class MainPanel(wx.Panel):
        def __init__(self, parent, *args, **kwargs):
            super().__init__(parent, *args, **kwargs)
    
            self.label_1 = wx.StaticText(self, label='This is my label')
            sizer = wx.BoxSizer(wx.VERTICAL)
            sizer.Add(self.label_1)
            self.SetSizer(sizer)
    
    
    if __name__ == '__main__':
        wx_app = wx.App()
        MainFrame()
        wx_app.MainLoop()
    

    module_2.py

    def ChangeLabel():
        with open('label_text.txt', 'w') as f_label:
            f_label.write('New Label Text')
    
    ChangeLabel()