3

I'm trying to pass the directory the user chooses back to the wx.TextCtrl named ChooseRoot. This has not worked so far.

What am I doing wrong? I tried different things, but either it hangs or I get this error message.

Traceback (most recent call last):
File "F:\Indexinator3000_x64.pyw", line 78, in OnChooseRoot
self.ChooseRoot.SetValue("Hello")
AttributeError: 'MainPanel' object has no attribute 'ChooseRoot'

import wx 

ID_EXIT = 110

class MainPanel(wx.Panel):
    def __init__(self, parent, id):
        wx.Panel.__init__(self, parent, id)
        self.parent = parent

        #------------- Setting up the buttons
        self.Run = wx.Button(self, label="Run")
        self.Run.Bind(wx.EVT_BUTTON, self.OnRun )
        self.ExitB = wx.Button(self, label="Exit")
        self.ExitB.Bind(wx.EVT_BUTTON, self.OnExit)

        #------------- Setting up Static text
        self.labelChooseRoot = wx.StaticText(self, label ="Root catalog: ") 
        self.labelScratchWrk = wx.StaticText(self, label ="Sratch workspace: ")
        self.labelMergeFile = wx.StaticText(self, label ="Merge file: ")

        #------------ Setting up inputtext
        self.ChooseRoot = wx.TextCtrl(self, -1, size=(210,-1))
        self.ChooseRoot.Bind(wx.EVT_LEFT_UP, self.OnChooseRoot)
        self.ScratchWrk = wx.TextCtrl(self, -1, size=(210,-1))
        self.MergeFile = wx.TextCtrl(self, -1, size=(210,-1))


        #------------- Setting up the outputbox
        self.Output = wx.TextCtrl(self, style=wx.TE_MULTILINE|wx.TE_READONLY)

        #------------- Setting up the sizer
        SizerF = wx.FlexGridSizer(3,2,5,5)
        SizerF.Add(labelChooseRoot)      #row 1, col 1
        SizerF.Add(ChooseRoot)           #row 1, col 2
        SizerF.Add(labelScratchWrk)      #row 2, col 1
        SizerF.Add(ScratchWrk)           #row 2, col 2
        SizerF.Add(labelMergeFile)       #row 3, col 1
        SizerF.Add(MergeFile)            #row 3, col 2

        SizerB = wx.BoxSizer(wx.VERTICAL)
        SizerB.Add(Run, 1, wx.ALIGN_RIGHT|wx.ALL, 5)
        SizerB.Add(ExitB, 0, wx.ALIGN_RIGHT|wx.ALL, 5)

        Sizer1 = wx.BoxSizer()
        Sizer1.Add(SizerF, 0, wx.ALIGN_RIGHT | wx.EXPAND | wx.ALL, 10)
        Sizer1.Add(SizerB, 0, wx.ALIGN_RIGHT | wx.EXPAND | wx.ALL)

        Sizer2 = wx.BoxSizer()
        Sizer2.Add(Output, 1, wx.EXPAND | wx.ALL, 5)

        SizerFinal = wx.BoxSizer(wx.VERTICAL)
        SizerFinal.Add(Sizer1, 0, wx.ALIGN_RIGHT | wx.EXPAND | wx.ALL)
        SizerFinal.Add(Sizer2, 1, wx.ALIGN_RIGHT | wx.EXPAND | wx.ALL)


        self.SetSizerAndFit(SizerFinal)

    #--- START EVENT HANDLERS

    def OnChooseRoot(self, Event=None):
        # In this case we include a "New directory" button. 
        dlg = wx.DirDialog(self, "Choose a directory:",
                          style=wx.DD_DEFAULT_STYLE
                           #| wx.DD_DIR_MUST_EXIST
                           #| wx.DD_CHANGE_DIR
                           )

        # If the user selects OK, then we process the dialog's data.
        # This is done by getting the path data from the dialog - BEFORE
        # we destroy it. 
        if dlg.ShowModal() == wx.ID_OK:
            RootPath = dlg.GetPath()
            self.ChooseRoot.SetValue(RootPath)

        # Only destroy a dialog after you're done with it.
        dlg.Destroy()

    def OnRun(self, Event=None):
        #First check if any of the boxes is empty
        pass

    def OnExit(self, Event=None):
        self.GetParent().Close()


    #--- END EVENT HANDLERS

class MainWindow(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, wx.ID_ANY, title, size = (430,330),
                          style = wx.DEFAULT_FRAME_STYLE | wx.NO_FULL_REPAINT_ON_RESIZE | wx.STAY_ON_TOP)
        self.CreateStatusBar() 
        #------------- Setting up the menu
        filemenu = wx.Menu()
        filemenu.Append(ID_EXIT, "E&xit", "Exit the program")
        #------------- Creating the menu
        menubar = wx.MenuBar()
        menubar.Append(filemenu, "&File")
        self.SetMenuBar(menubar)
        #---------- Setting menu event handlers
        wx.EVT_MENU(self, ID_EXIT, self.OnExit)                    
        #--- Add MainPanel
        self.Panel = MainPanel(self, -1)

        self.SetMaxSize(self.GetSize()) #Sets the Maximum size the window can have
        self.SetMinSize(self.GetSize()) #Sets the Minimum size the window can have
        #Centre on Screen
        self.CentreOnScreen()

        ###---- SHOW THE WINDOW
        self.Show(True)

    def OnExit(self,  event):
        self.Close(True) # Close the Frame
    #--- END EVENT HANDLERS ---------------------------------



if __name__=='__main__':

    try:
        app = wx.PySimpleApp()
        frame = MainWindow(None, -1, "IndexGenerator")
        app.MainLoop()
    finally:
        del app

1 Answer 1

3

Read carefully advices that I have given you in your previous question. Especially:

  • use object properties for the widgets, so you do not loose track of them (self.ChooseRoot =...)
  • use more desriptive widget names (self.labelChooseRoot)

Outside of the __init__ method (aka constructor) you loose track of your widgets. You have to add them to your MainPanel object as attributes.

class MainPanel(wx.Panel):
    def __init__(self, parent, id):
        ...
        self.ChooseRoot = wx.TextCtrl(self, size=(210, -1))
        ...

    def OnChooseRoot(self, event=None):
        ...
        self.ChooseRoot.SetValue(RootPath)
        ...

I would also recommend some reading on OOP concepts. Maybe you can start from here.

Edit: You nearly got it working. The idea was OK, you just forgot a few places. I have updated your code to conform with my "standard", deleted some unnecessary copy/paste stuff and some other minor tweaks. Use some compare software and do a careful compare to see the changes if you like.

import wx 

ID_EXIT = 110

class MainPanel(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)

        self.buttonRun = wx.Button(self, label="Run")
        self.buttonRun.Bind(wx.EVT_BUTTON, self.OnRun )
        self.buttonExit = wx.Button(self, label="Exit")
        self.buttonExit.Bind(wx.EVT_BUTTON, self.OnExit)

        self.labelChooseRoot = wx.StaticText(self, label ="Root catalog: ") 
        self.labelScratchWrk = wx.StaticText(self, label ="Scratch workspace: ")
        self.labelMergeFile = wx.StaticText(self, label ="Merge file: ")

        self.textChooseRoot = wx.TextCtrl(self, size=(210, -1))
        self.textChooseRoot.Bind(wx.EVT_LEFT_UP, self.OnChooseRoot)
        self.textScratchWrk = wx.TextCtrl(self, size=(210, -1))
        self.textMergeFile = wx.TextCtrl(self, size=(210, -1))
        self.textOutput = wx.TextCtrl(self, style=wx.TE_MULTILINE | wx.TE_READONLY)

        self.sizerF = wx.FlexGridSizer(3, 2, 5, 5)
        self.sizerF.Add(self.labelChooseRoot)  #row 1, col 1
        self.sizerF.Add(self.textChooseRoot)   #row 1, col 2
        self.sizerF.Add(self.labelScratchWrk)  #row 2, col 1
        self.sizerF.Add(self.textScratchWrk)   #row 2, col 2
        self.sizerF.Add(self.labelMergeFile)   #row 3, col 1
        self.sizerF.Add(self.textMergeFile)    #row 3, col 2

        self.sizerB = wx.BoxSizer(wx.VERTICAL)
        self.sizerB.Add(self.buttonRun, 1, wx.ALIGN_RIGHT|wx.ALL, 5)
        self.sizerB.Add(self.buttonExit, 0, wx.ALIGN_RIGHT|wx.ALL, 5)

        self.sizer1 = wx.BoxSizer()
        self.sizer1.Add(self.sizerF, 0, wx.ALIGN_RIGHT | wx.EXPAND | wx.ALL, 10)
        self.sizer1.Add(self.sizerB, 0, wx.ALIGN_RIGHT | wx.EXPAND | wx.ALL)

        self.sizer2 = wx.BoxSizer()
        self.sizer2.Add(self.textOutput, 1, wx.EXPAND | wx.ALL, 5)

        self.sizerFinal = wx.BoxSizer(wx.VERTICAL)
        self.sizerFinal.Add(self.sizer1, 0, wx.ALIGN_RIGHT | wx.EXPAND | wx.ALL)
        self.sizerFinal.Add(self.sizer2, 1, wx.ALIGN_RIGHT | wx.EXPAND | wx.ALL)

        self.SetSizerAndFit(self.sizerFinal)


    def OnChooseRoot(self, event):
        dlg = wx.DirDialog(self, "Choose a directory:", style=wx.DD_DEFAULT_STYLE)
        if dlg.ShowModal() == wx.ID_OK:
            root_path = dlg.GetPath()
            self.textChooseRoot.SetValue(root_path)
        dlg.Destroy()

    def OnRun(self, event):
        #First check if any of the boxes is empty
        pass

    def OnExit(self, event):
        self.GetParent().Close()


class MainWindow(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, title="IndexGenerator", size=(430, 330), 
                          style=((wx.DEFAULT_FRAME_STYLE | wx.NO_FULL_REPAINT_ON_RESIZE | 
                                  wx.STAY_ON_TOP) ^ wx.RESIZE_BORDER))
        self.CreateStatusBar() 

        self.fileMenu = wx.Menu()
        self.fileMenu.Append(ID_EXIT, "E&xit", "Exit the program")
        self.menuBar = wx.MenuBar()
        self.menuBar.Append(self.fileMenu, "&File")
        self.SetMenuBar(self.menuBar)
        wx.EVT_MENU(self, ID_EXIT, self.OnExit)                    

        self.Panel = MainPanel(self)

        self.CentreOnScreen()
        self.Show()

    def OnExit(self,  event):
        self.Close()

if __name__ == "__main__":
    app = wx.App(False)
    frame = MainWindow()
    app.MainLoop()
Sign up to request clarification or add additional context in comments.

4 Comments

Hello again. Ive tried this, but pytonw.exe freezes. Thats why I thought it was wrong. The main program is if __name__=='__main__': try: app = wx.PySimpleApp() frame = MainWindow(None, -1, "IndexGenerator") app.MainLoop() finally: del app Maybe this causes it? Should I add self to the sizer as well? Tried adding self to all but sizers and pytonw.exe still hangs. Sorry about the layout, problems formatting the comment.
Please update your question above with whole runnable program.
I have updated your code. Read it carefully to get all the points.
Thanks alot Fenikso. See you did some changes regarding app and the MainWindow class. I'll check it out. =)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.