通过使用wx.GenericDirCtrl选择文件夹,在具有按钮的文件夹中列出文件

时间:2017-01-02 18:38:25

标签: python python-2.7 wxpython

我正在尝试使用包含GenericDirCtrl wiget的左窗格创建一个splitwindow框架,这将允许我选择包含pdf文件的目录/文件夹,然后我想以按钮的形式在右窗格中显示文件找到每个文件。我能够按需要显示UI,但我不确定如何使用GenricDirCtrl小部件中选择的文件夹刷新右窗格。能帮我解决一下这个问题吗?我尝试声明一个全局变种但是没有用,我对wxpython很新,所以请原谅我缺乏技巧..

    #!/usr/bin/env python
import datetime
import glob
import os
import sys
import wx
import wx.lib.scrolledpanel as scrolled

global directory
global pdfpath
directory = []
print directory

if directory != []: 
    valid_pdffiles = []
    pdfpath = []

    valid_pdffiles += [each for each in os.listdir(directory) if each.endswith('.pdf')]
    #print valid_pdffiles
    for files in valid_pdffiles:
        pdfpath.append(str(directory + "/" + files))
    print pdfpath
else:
    pdfpath = ['testing_blank.pdf']

for files in pdfpath:
    print "pdf - " + files

class scrolledpanel(scrolled.ScrolledPanel):
    def __init__(self,parent,id):

        scrolled.ScrolledPanel.__init__(self,parent, id,style = wx.TAB_TRAVERSAL|wx.SUNKEN_BORDER)
        self.SetBackgroundColour(wx.NamedColour("pink"))
        self.sizer = wx.WrapSizer()
        self.SetupScrolling(scroll_x = False)
        self.parent = parent        
        self.addButton(self.sizer , 1000)
        self.SetSizer(self.sizer )
        self.Bind(wx.EVT_SIZE, self.onSize)
        self.SetAutoLayout(1)
        self.SetupScrolling()
        self.Layout()

    def onSize(self, evt):
        size = self.GetSize()
        vsize = self.GetVirtualSize()
        self.SetVirtualSize((size[0], vsize[1]))
        evt.Skip()

    def OnButton(self, Event, button_label):
        print "In OnButton:", button_label  

    def addButton(self, sizer, num):
        print "Executed addButton here..."
        for files in pdfpath:
            #print "PDFFROMADDBUTTON - " + files
            btn =wx.Button( self, wx.ID_ANY, "btn_"+str(files), wx.DefaultPosition, size=(100,100), style=wx.ALIGN_CENTER)
            sizer.Add(btn, 0, wx.ALL, 10)

class MainWindow(wx.Frame):

    def __init__(self, parent=None, start_fresh=False):
        wx.Frame.__init__(self, parent, wx.ID_ANY, u'This is App title..', wx.DefaultPosition, size=(800,600), name=u'Thisisthename..', style=wx.DEFAULT_FRAME_STYLE)
        locale = wx.Locale(wx.LANGUAGE_ENGLISH)
        self._init_contents()

    def _init_contents(self):
        self.statusBar = self.CreateStatusBar()

        sizer = wx.BoxSizer(orient=wx.VERTICAL)

        self.dirPicker = wx.DirPickerCtrl (self, id=wx.ID_ANY, style=wx.DIRP_DIR_MUST_EXIST | wx.DIRP_USE_TEXTCTRL)
        sizer.Add(
                self.dirPicker,
                0,           # make vertically unstretchable
                wx.EXPAND |  # make horizontally stretchable
                wx.ALL,      # and make border all around
                )

        self.splitter1 = wx.SplitterWindow(self, id=wx.ID_ANY, style=wx.SP_3D)

        sizer.Add(
                self.splitter1,
                1,           # make vertically stretchable
                wx.EXPAND |  # make horizontally stretchable
                wx.ALL,      # and make border all around
                )
        self.textCtrl1 = scrolledpanel(self.splitter1,-1)

        self.dir = wx.GenericDirCtrl(self.splitter1, wx.ID_ANY, 
                                     dir="C:/python27",
                                     filter="*.pdf"
                                     )
        self.splitter1.SplitVertically(self.dir, self.textCtrl1)
        self.splitter1.SetSashGravity(0.2)

        tree = self.dir.GetTreeCtrl()

        wx.EVT_TREE_SEL_CHANGED(self, tree.GetId(), self.OnSelectTreeCtrlItem)
        self.Bind(wx.EVT_DIRPICKER_CHANGED, self.OnSelectDirPicker)

        self.SetSizerAndFit(sizer)

    def OnSelectTreeCtrlItem(self, event):
        '''user selected something in the directory list tree control'''
        if not isinstance(event, wx.Event):
            self.setStatusText( "Not an event: %s" % str(event) )
            event.Skip()
            return
        selectedItem = self.dir.GetPath()
        print 'selected: ' + selectedItem
        self.selectedDir = selectedItem
        scrolledpanel.refresh


    def OnSelectDirPicker(self, event):
        '''user changed the text or browsed to a directory in the picker'''
        if not isinstance(event, wx.Event):
            self.setStatusText( "Not an event: %s" % str(event) )
            event.Skip()
            return
        selectedItem = self.dirPicker.GetPath()
        print 'selectedDir: ' + selectedItem

def main():
    '''presents the GUI'''
    app = wx.App()
    win = MainWindow(None)
    win.Show()
    app.MainLoop()


if __name__ == '__main__':
    main()

建议后编辑代码:

#!/usr/bin/env python
import datetime
import glob
import os
import sys
import wx
import wx.lib.scrolledpanel as scrolled

global directory
global pdfpath
directory = []
print directory

if directory != []: 
    valid_pdffiles = []
    pdfpath = []

    valid_pdffiles += [each for each in os.listdir(directory) if each.endswith('.pdf')]
    #print valid_pdffiles
    for files in valid_pdffiles:
        pdfpath.append(str(directory + "/" + files))
    print pdfpath
else:
    pdfpath = ['testing_blank.pdf']

for files in pdfpath:
    print "pdf - " + files

class scrolledpanel(scrolled.ScrolledPanel):
    def __init__(self,parent,id):

        scrolled.ScrolledPanel.__init__(self,parent, id,style = wx.TAB_TRAVERSAL|wx.SUNKEN_BORDER)
        self.SetBackgroundColour(wx.NamedColour("pink"))
        self.sizer = wx.WrapSizer()
        self.SetupScrolling(scroll_x = False)
        self.parent = parent        
        self.addButton()
        self.SetSizer(self.sizer )
        self.Bind(wx.EVT_SIZE, self.onSize)
        self.SetAutoLayout(1)
        self.SetupScrolling()
        self.Layout()

    def onSize(self, evt):
        size = self.GetSize()
        vsize = self.GetVirtualSize()
        self.SetVirtualSize((size[0], vsize[1]))
        evt.Skip()

    def OnButton(self, Event, button_label):
        print "In OnButton:", button_label  

    def addButton(self):
        print "Executed addButton here..."

        self.sizer.DeleteWindows() # destroy all the chilren this sizer has
        global pdfpath
        print pdfpath
        for files in pdfpath:
            #print "PDFFROMADDBUTTON - " + files
            btn =wx.Button( self, wx.ID_ANY, "btn_"+str(files), wx.DefaultPosition, size=(100,100), style=wx.ALIGN_CENTER)
            btn.SetToolTipString(str(files))
            self.sizer.Add(btn, 0, wx.ALL, 10)
        self.sizer.Layout()
        self.FitInside()
        #self.Layout()

class MainWindow(wx.Frame):

    def __init__(self, parent=None, start_fresh=False):
        wx.Frame.__init__(self, parent, wx.ID_ANY, u'This is App title..', wx.DefaultPosition, size=(800,600), name=u'Thisisthename..', style=wx.DEFAULT_FRAME_STYLE)
        locale = wx.Locale(wx.LANGUAGE_ENGLISH)
        self._init_contents()

    def _init_contents(self):
        self.statusBar = self.CreateStatusBar()

        sizer = wx.BoxSizer(orient=wx.VERTICAL)

        self.dirPicker = wx.DirPickerCtrl (self, id=wx.ID_ANY, style=wx.DIRP_DIR_MUST_EXIST | wx.DIRP_USE_TEXTCTRL)
        sizer.Add(
                self.dirPicker,
                0,           # make vertically unstretchable
                wx.EXPAND |  # make horizontally stretchable
                wx.ALL,      # and make border all around
                )

        self.splitter1 = wx.SplitterWindow(self, id=wx.ID_ANY, style=wx.SP_3D)

        sizer.Add(
                self.splitter1,
                1,           # make vertically stretchable
                wx.EXPAND |  # make horizontally stretchable
                wx.ALL,      # and make border all around
                )
        self.textCtrl1 = scrolledpanel(self.splitter1,-1)

        self.dir = wx.GenericDirCtrl(self.splitter1, wx.ID_ANY, 
                                     dir="C:/python27",
                                     filter="*.pdf"
                                     )
        self.splitter1.SplitVertically(self.dir, self.textCtrl1)
        self.splitter1.SetSashGravity(0.2)

        tree = self.dir.GetTreeCtrl()

        wx.EVT_TREE_SEL_CHANGED(self, tree.GetId(), self.OnSelectTreeCtrlItem)
        self.Bind(wx.EVT_DIRPICKER_CHANGED, self.OnSelectDirPicker)

        self.SetSizerAndFit(sizer)


    def OnSelectTreeCtrlItem(self, event):
        '''user selected something in the directory list tree control'''
        if not isinstance(event, wx.Event):
            self.setStatusText( "Not an event: %s" % str(event) )
            event.Skip()
            return
        selectedItem = self.dir.GetPath()
        print 'selected: ' + selectedItem
        self.selectedDir = selectedItem
        global pdfpath
        pdfpath = selectedItem
        from os import listdir
        from os.path import isfile, join
        pdfpath = [f for f in listdir(pdfpath) if isfile(join(pdfpath, f))]
        print pdfpath
        self.textCtrl1.addButton()


    def OnSelectDirPicker(self, event):
        '''user changed the text or browsed to a directory in the picker'''
        if not isinstance(event, wx.Event):
            self.setStatusText( "Not an event: %s" % str(event) )
            event.Skip()
            return
        selectedItem = self.dirPicker.GetPath()
        print 'selectedDir: ' + selectedItem
        global pdfpath
        pdfpath = selectedItem
        from os import listdir
        from os.path import isfile, join
        pdfpath = [f for f in listdir(pdfpath) if isfile(join(pdfpath, f))]
        print pdfpath
        self.textCtrl1.addButton()

def main():
    '''presents the GUI'''
    app = wx.App()
    win = MainWindow(None)
    win.Show()
    app.MainLoop()


if __name__ == '__main__':
    main()

1 个答案:

答案 0 :(得分:1)

我认为你需要自己重新填充按钮给sizer。

基本上,addButton方法可以修改为:

def addButton(self):
    print "Executed addButton here..."

    self.sizer.DeleteWindows() # destroy all the chilren this sizer has

    for files in pdfpath:
        #print "PDFFROMADDBUTTON - " + files
        btn =wx.Button( self, wx.ID_ANY, "btn_"+str(files), wx.DefaultPosition, size=(100,100), style=wx.ALIGN_CENTER)
        self.sizer.Add(btn, 0, wx.ALL, 10)
    self.Layout()

sizer已经是一个类成员,因此您可以将其称为self.sizer,无需将其作为arg传递。

此外,您必须刷新OnSelectTreeCtrlItem中的pdf文件列表,如:

def OnSelectTreeCtrlItem(self, event):
    '''user selected something in the directory list tree control'''
    if not isinstance(event, wx.Event):
        self.setStatusText( "Not an event: %s" % str(event) )
        event.Skip()
        return
    selectedItem = os.path.dirname(self.dir.GetPath())
    print 'selected: ' + selectedItem
    self.selectedDir = selectedItem

    global pdfpath
    pdfpath = []
    pattern = os.path.join(selectedItem, '*.pdf')
    for f in glob.glob(pattern):
        pdfpath.append(f)
    self.textCtrl1.addButton()