Advertisement
yclee126

wxPython DND file loader panel

Nov 12th, 2022
720
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.72 KB | None | 0 0
  1. import wx
  2. from pathlib import Path
  3.  
  4. class DNDButton(wx.Panel):
  5.     """wxPython Drag & Drop file loader panel
  6.  
  7.    Simple DND button with a title bar.
  8.    Drop files on the button or click the button to load files.
  9.    The button also displays the first loaded file's name with file count.
  10.    """
  11.  
  12.     def __init__(self, parent, title, listener=lambda files: True, wildcard='All files|*.*'):
  13.         """Default initializer.
  14.  
  15.        parent: wx.Window
  16.        title: str
  17.        listener: (files: list[str] -> Boolean) (True: Keep files, False: Clear files)
  18.        wildcard: str
  19.        """
  20.         wx.Panel.__init__(self, parent)
  21.         self.SetMinSize((0, 0)) # override minsize for text wrapping
  22.  
  23.         self.list = []
  24.         self.listener = listener
  25.         self.wildcard = wildcard
  26.        
  27.         sizer = wx.BoxSizer(wx.VERTICAL)
  28.         self.SetSizer(sizer)
  29.  
  30.         self.label = wx.StaticText(self, label=title)
  31.         sizer.Add(self.label, flag=wx.CENTER)
  32.  
  33.         self.button = wx.Button(self, label='Drop files here\nor click to select files')
  34.         sizer.Add(self.button, flag=wx.UP|wx.EXPAND, border=5, proportion=1)
  35.         self.button.Bind(wx.EVT_BUTTON, self.onOpenFiles)
  36.         self.button.SetDropTarget(self.FileDrop(self))
  37.  
  38.         self.Layout()
  39.    
  40.     def onOpenFiles(self, evt):
  41.         with wx.FileDialog(self, 'Open files', wildcard=self.wildcard, style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST | wx.FD_MULTIPLE) as fileDialog:
  42.             if fileDialog.ShowModal() == wx.ID_CANCEL:
  43.                 return
  44.            
  45.             files = fileDialog.GetPaths()
  46.             self.onFilesAdded(files)
  47.    
  48.     def onFilesAdded(self, files):
  49.         # set list
  50.         self.list = files
  51.  
  52.         # check if empty
  53.         if len(self.list) == 0:
  54.             self.button.SetLabel('Drop files here\nor click to select files')
  55.             return
  56.        
  57.         # set button label
  58.         first_filename = Path(self.list[0]).name
  59.  
  60.         if len(self.list) == 1:
  61.             self.button.SetLabel(f' \n{first_filename}\n ') # inserting linebreaks enables the button to wrap the text
  62.         else:
  63.             self.button.SetLabel(f'{first_filename}\nTotal {len(self.list)} files')
  64.  
  65.         # check listener
  66.         valid = self.listener(self.list)
  67.         if not valid:
  68.             self.clearFiles()
  69.    
  70.     def clearFiles(self):
  71.         """Clear all files
  72.        """
  73.         self.onFilesAdded([])
  74.    
  75.     class FileDrop(wx.FileDropTarget):
  76.         def __init__(self, parent):
  77.             wx.FileDropTarget.__init__(self)
  78.             self.parent = parent
  79.      
  80.         def OnDropFiles(self, x, y, filenames):
  81.             self.parent.onFilesAdded(filenames)
  82.             return True
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement