简体   繁体   中英

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?

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.

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()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM