0

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()
newby73
  • 45
  • 11
  • without seeing the code its really hard to say. Can you post it please? – Igor Apr 18 '23 at 15:32
  • Updated just now, forgot to add the code. – newby73 Apr 18 '23 at 15:36
  • Is there any reason you're calling the second module as a subprocess? Seems a weird way of doing things. What are you trying to achieve? – Psionman Apr 18 '23 at 16:33
  • @Psionman this is a prototype for a much larger project I am working on. Essentially, the MainFile will supply the wxGlade GUI, and the SecondFile will provide various tests, and the two files will interact with each other via subprocess + input/output files. – newby73 Apr 18 '23 at 16:37
  • @Psionman I realize this is a strange method, but it is necessary... unless of course it proves to be one of wxPython's limitations. – newby73 Apr 18 '23 at 16:39
  • I think it might be a problem with running the two modules in different processes. The second just imports a file, it doesn't run the app, so clearly it doesn't know about label_1 (BTW it should be self.label_1 if you're trying to reference it from outside \__.init__). And it's considered bad practice to put elements in the Frame - that's what panels are for. You've not indicated how you're starting the wxPython loop – Psionman Apr 18 '23 at 16:52
  • Make `label_1`, `self.label_1` it is an instance variable and is then accessible see: https://www.geeksforgeeks.org/different-ways-to-access-instance-variable-in-python/ – Rolf of Saxony Apr 18 '23 at 17:03
  • @Psionman Do you think I should use something other than subprocess? – newby73 Apr 18 '23 at 17:19
  • @RolfofSaxony Thank you, but I need accessibility across modules. – newby73 Apr 18 '23 at 17:20
  • Does this help? self.label_1 = – toyota Supra Apr 18 '23 at 17:58
  • @toyotaSupra No, it does not - it results in the same error: 'MyFrame' has no attribute 'label_1' – newby73 Apr 18 '23 at 18:03
  • You have two independent processes. You could read the value of the label from a file in process 1 and then check it periodically in a timed loop. Then use process 2 to update the value on file which will be picked up by 1. Not very elegant, but it'd work – Psionman Apr 18 '23 at 18:20
  • @newby73, can you describe in plain English what are you looking for? The way you are trying to do things IS pretty weird, but since we do not know you intentions, we can't give you the resolutions. – Igor Apr 18 '23 at 18:31
  • `"This file contains a subprocess (irrelevant) which runs the second file."` No, it isn't `irrelevant` that would be running an independent process. – Rolf of Saxony Apr 19 '23 at 10:55

1 Answers1

0

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()
Psionman
  • 3,084
  • 1
  • 32
  • 65
  • This is exactly what I needed - a brilliant solution to an odd question. Thank you. – newby73 Apr 19 '23 at 12:39
  • This is only a string and glue solution and not very elegant. Before you go on you need to look at how python imports and modules work (your initial idea went down the wrong rabbit hole). Depending on what you're trying to achieve look at json to define label values etc. – Psionman Apr 20 '23 at 08:34