dot.Py
dot.Py

Reputation: 5157

WxPython GUI programming - NameError: name "self" is not defined

I'm creating a program to edit a .txt file.

I have 2 files inside a folder:

gui.py & edit_text.py

Here's the code for gui.py

# -*- coding: utf-8 -*- 
import wx
import wx.xrc

class Main ( wx.Frame ):
    
    def __init__( self, parent ):
        wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = u"Editor MAVB", pos = wx.DefaultPosition, size = wx.Size( 250,180 ), style = wx.CAPTION|wx.CLOSE_BOX|wx.MINIMIZE_BOX|wx.SYSTEM_MENU|wx.TAB_TRAVERSAL )
        
        self.SetSizeHintsSz( wx.Size( 250,180 ), wx.Size( 250,180 ) )
        
        layout_sizer = wx.BoxSizer( wx.VERTICAL )
        
        self.text1 = wx.StaticText( self, wx.ID_ANY, u"Escolha o arquivo que será editado:", wx.DefaultPosition, wx.DefaultSize, 0 )
        self.text1.Wrap( -1 )
        layout_sizer.Add( self.text1, 1, wx.ALL|wx.EXPAND, 5 )
        
        self.filePicker = wx.FilePickerCtrl( self, wx.ID_ANY, wx.EmptyString, u"Selecione um arquivo", u"*.txt", wx.DefaultPosition, wx.Size( 210,-1 ), wx.FLP_DEFAULT_STYLE|wx.FLP_FILE_MUST_EXIST|wx.FLP_SMALL )
        layout_sizer.Add( self.filePicker, 0, wx.ALL|wx.EXPAND, 5 )
        
        self.null_text = wx.StaticText( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 )
        self.null_text.Wrap( -1 )
        layout_sizer.Add( self.null_text, 0, wx.ALL, 5 )
        
        self.edit_button = wx.Button( self, wx.ID_ANY, u"Alterar arquivo", wx.DefaultPosition, wx.DefaultSize, 0 )
        layout_sizer.Add( self.edit_button, 0, wx.ALL, 5 )
        
        self.status_text = wx.StaticText( self, wx.ID_ANY, u"Aguardando arquivo...", wx.DefaultPosition, wx.DefaultSize, 0 )
        self.status_text.Wrap( -1 )
        layout_sizer.Add( self.status_text, 0, wx.ALL|wx.EXPAND, 5 )
        
        
        self.SetSizer( layout_sizer )
        self.Layout()
        
        self.Centre( wx.BOTH )
        
        # Connect Events
        self.edit_button.Bind( wx.EVT_BUTTON, self.editar_txt )
    
    def __del__( self ):
        pass
    
    
    # Virtual event handlers, overide them in your derived class
    def editar_txt( self, event ):
        event.Skip()
    

And here is the code for edit_txt.py

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

class MyFrame(gui.Main):
    def __init__(self, parent):
        gui.Main.__init__(self, parent)
        
    infile = self.filePicker.GetTextCtrlValue()
    outfile_path = infile[:len(infile)-4] + "_editado.txt"
    
    def editar_txt(self, infile):
        outfile = []
        with open(infile) as f:
            for line in f:
                line_ed = line.replace("|VENDAS|0|", "|VENDAS|2|")
                outfile.append(line_ed)
        with open(outfile_path, "w") as g:
            for line in outfile:
                g.write(line)

        f.close()
        g.close()
  
class MyApp(wx.App):
    def OnInit(self):
        self.frame = MyFrame(None)
        self.SetTopWindow(self.frame)
        self.frame.Show(True)
        print("\n----------------------------------------\nEditor MAVB - inicializado com sucesso. \n----------------------------------------")
        return True
        
if __name__ == "__main__":
    app = MyApp(redirect=False)
    app.MainLoop() 

When I enter into the program folder and run edit_txt.py, I got the following error:

Error in line 
infile = self.filePicker.GetTextCtrlValue()
NameError: name 'self' is not defined
  1. I've created a Main class in gui.py
  2. Imported gui.py script into edit_txt.py
  3. Created a inherited MyFrame class from the gui.Main class
  4. Initialized MyFrame class as soon as I open the program
  5. Then I tried to get the infile path using the command: infile = self.filePicker.GetTextCtrlValue()

Questions:

Why isn't this working?

How can I make it work?

Upvotes: 0

Views: 705

Answers (2)

user5780275
user5780275

Reputation:

You are trying to access an instance property inherited from gui.Main as a class property. Generally speaking, you are trying to statically access a non-static property.

If you define infile and outfile_path as instance properties for MyFrame, you can then access them with self.Property.

(Please note that this way you need to change references to the editar_txt method where it is referenced, because the argument is no longer necessary.)

Below the modified MyFrame class in edit_txt.py :

class MyFrame(gui.Main):
    def __init__(self, parent):
        gui.Main.__init__(self, parent)

        self.infile = self.filePicker.GetTextCtrlValue()
        self.outfile_path = self.infile[:len(self.infile)-4] + "_editado.txt"

    def editar_txt(self):
        outfile = []
        with open(self.infile) as f:
            for line in f:
                line_ed = line.replace("|VENDAS|0|", "|VENDAS|2|")
                outfile.append(line_ed)
        with open(self.outfile_path, "w") as g:
            for line in outfile:
                g.write(line)

        f.close()
        g.close()

Upvotes: 1

kindall
kindall

Reputation: 184171

Why isn't it working? Because the following line:

infile = self.filePicker.GetTextCtrlValue()

is outside any function, and is in the class definition. It is trying to execute this line as the class is being defined to create an infile attribute on the class, and as self is not defined at this time, it complains about self not being defined.

How can you make it work? Presumably, you intended that line and the one after it to be in your __init__() method. Indent them accordingly.

Upvotes: 1

Related Questions