wxpython refresh window on button press

≯℡__Kan透↙ 提交于 2021-01-28 02:03:17

问题


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:


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



来源:https://stackoverflow.com/questions/12742245/wxpython-refresh-window-on-button-press

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!