2
votes

I have been having some trouble with my Python program. Basically, it is a very very simple file manager.

I have been trying to get it to move between folders (user clicks a folder, program refreshes display and shows contents of folder).

The problem I am having is that I cant seem to get the button to refresh the display and then fill it with the new folders and files when clicked.

Here is the code I am using and it is on Linux.

import wx
import fileBrowser

class interface(wx.Frame):

    def __init__(self, parent, id):
        '''(object, int) --> None
        Set up wx python in a frame and displays it and contents defined in this function on the screen.'''

        wx.Frame.__init__(self, parent, id, "Bronto", size = (800, 600))
        panel = wx.Panel(self)
        self.createPanels()
        contents = fileBrowser.print_items("/")
        wx.StaticText(panel, -1, "/", (50, 10))
        col = 50
        row = 50
        for items in contents:
            name       = items
            col, row   = self.makeIcons(panel, (800, 600), name, col, row)

    def makeIcons(self, panel, param, name, col, row):
        '''(object, object) --> None
        Place a button on the window that uses an image as its icon.'''

        pic = wx.Image("folder.png", wx.BITMAP_TYPE_PNG).ConvertToBitmap()
        self.button  = wx.BitmapButton(panel, -1, pic, pos = (col, row))
        wx.StaticText(panel, -1, name, (col + 10, row + 40))
        self.Bind(wx.EVT_BUTTON, self.displayContents, self.button)
        self.button.SetDefault()

        if(col < 600):
            return col + 90, row
        else:
            col = 50
            return col, row + 80


    def createPanels(self):
        '''(object) --> None
        Create and place both menu and status bars on the window.'''

        status     = self.CreateStatusBar()
        menubar    = wx.MenuBar()
        File       = wx.Menu()
        Edit       = wx.Menu()

        menubar.Append(File,"File")
        menubar.Append(Edit, "Edit")
        new = wx.MenuItem(File, 101, '&New\tCtrl+N', 'Creates a new document')
        File.AppendItem(new)
        self.Bind(wx.EVT_MENU, self.NewApplication, id=101)
        self.SetMenuBar(menubar)


    def NewApplication(self, event):
        app = wx.PySimpleApp()
        frame = interface(parent = None, id =1)

        frame.Show()
        app.MainLoop()


    def displayContents(self, event):
        '''(event) --> None
        Display the contents of the folder clicked on'''



        #self.panel.Destroy();
        #self.panel = wx.Panel(self)
        self.Refresh(True)
        contents = fileBrowser.print_items("/home")
        col = 50
        row = 50
        for items in contents:
            name       = items
            wx.Yield()
            col, row   = self.makeIcons(panel, (800, 600), name, col, row)

if __name__ == "__main__":
    app = wx.PySimpleApp()
    frame = interface(parent = None, id =1)

    frame.Show()
    app.MainLoop()

And here is the fileBrower program (at the moment I only look at folders, but I will change it later)

import os
import os.path

def print_items(d):
    '''(str) -> NoneType
    Print the list of files and directories in directory d, recursively,
    prefixing each with indentation.'''

    icons = []
    #print out the names of files and subdirectories
    for filename in os.listdir(d):
        subitem = os.path.join(d, filename)
        if os.path.isdir(subitem):
            print filename
            icons.append(filename)

    return icons

@pthonm: I added the code you suggested but it doesnt seem to update it with the new stuff (it does clear the window though)

EDIT: Okay I almost have it working. I can get it to display the contents by using self.Refresh(True) but it only works if I dont use the self.panel.Destroy() method. So, any suggestions on how to get rid of the buttons and the text(see the displayContents method for what I added)?

EDIT2: I got it to work. What I did was, I added this to my displayContents method. This probably isnt the best way to do this though.

def displayContents(self, event):
    '''(event) --> None
    Display the contents of the folder clicked on'''

    self.panel.Destroy();
    self.panel = wx.Panel(self)
    self.createPanels()
    self.Update()
    wx.StaticText(self.panel, -1, location, (50, 10))
    contents = fileBrowser.print_items("/home/gum/Documents")
    col = 50
    row = 50
    for directory,name in contents.iteritems():
        col, row   = self.makeIcons(self.panel, (800, 600), name, col, row)
1
you thinking very difficult and complicated for such like this simple filemanager. there existing design patterns and its better for you, program according to the rules. here is an example with code, how to code a filemanager. "zetcode.com/wxpython/skeletons" Study this code and write it from scratch. my recommendation for you..! - fecub

1 Answers

1
votes

I think the problem is that you

  • Create new panel for each folder
  • Don't delete the old panels

I would suggest you to save the old panel somewhere at self.panel and call self.panel.Destroy();self.panel = wx.Panel(self) on each time.

The better option is to use wx.ListCtrl, catch EVT_LIST_ITEM_ACTIVATED and then delete the list and fill it with the items:

__init__:
self.ListCtrl = wx.ListCtrl(self)
self.listCtrl.InsertColumn(0, 'name')
self.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnChangeFolder, self.listCtrl)
self.il = wx.ImageList(16, 16)
self.il.Add(wx.Image("folder.png", wx.BITMAP_TYPE_PNG).ConvertToBitmap())
self.listCtrl.AssignImageList(self.il)
self.folders = fileBrowser.print_items("/home/gum/Documents")
self.UpdateList()
UpdateList:
self.listCtrl.DeleteAllItems()
for index, item in enumerate(self.folders):
    self.listCtrl.Append((item, ))
    self.listCtrl.SetItemImage(index, 0)
    # 0 is the ImageList index, change it for other icons
OnChangeFolder:
self.folders = file.Browser.print_items(self.listCtrl.GetFocusedItem().GetText())
self.UpdateList

BTW, the wx style indicates that methods and classes are also CamelCased, just that you know :)