2017-10-20 1 views
0

Erstens, this ist, was ich versuche, mit WxPython zu machen. Ich möchte, dass die Region mit der Bezeichnung "Bild 1" ein gezogenes Bild akzeptieren kann und dann, wenn ein Bild dort gezogen wird, durch ein Miniaturbild dieses Bildes ersetzt wird. Ich habe "Drag and Drop" in wxPython erforscht, aber ich kann nicht die Werkzeuge finden, die für mich benötigt werden, um dies zu tun.Erstellen einer Drag & Drop-Schnittstelle für Bilder in WxPython

Jede Hilfe, die mich auf dem richtigen Weg beginnen würde sehr geschätzt werden.

Antwort

1

Sie möchten die Pillow package zum Erstellen einer Miniaturansicht verwenden. Das andere Stück, das Sie wollen, ist wahrscheinlich die wx.FileDropTarget Klasse. Ich landete Sie folgendermaßen vorgehen:

import os 
import wx 

from PIL import Image 
from wx.lib.pubsub import pub 

PhotoMaxSize = 240 


class DropTarget(wx.FileDropTarget): 

    def __init__(self, widget): 
     wx.FileDropTarget.__init__(self) 
     self.widget = widget 

    def OnDropFiles(self, x, y, filenames): 
     print(filenames) 

     image = Image.open(filenames[0]) 
     image.thumbnail((PhotoMaxSize, PhotoMaxSize)) 
     image.save('thumbnail.png') 
     pub.sendMessage('dnd', filepath='thumbnail.png') 
     return True 


class PhotoCtrl(wx.App): 
    def __init__(self, redirect=False, filename=None): 
     wx.App.__init__(self, redirect, filename) 
     self.frame = wx.Frame(None, title='Photo Control') 

     self.panel = wx.Panel(self.frame) 
     pub.subscribe(self.update_image_on_dnd, 'dnd') 

     self.PhotoMaxSize = 240 

     self.createWidgets() 
     self.frame.Show() 

    def createWidgets(self): 
     instructions = 'Browse for an image' 
     img = wx.Image(240,240) 
     self.imageCtrl = wx.StaticBitmap(self.panel, wx.ID_ANY, 
             wx.Bitmap(img)) 
     filedroptarget = DropTarget(self) 
     self.imageCtrl.SetDropTarget(filedroptarget) 

     instructLbl = wx.StaticText(self.panel, label=instructions) 
     self.photoTxt = wx.TextCtrl(self.panel, size=(200,-1)) 
     browseBtn = wx.Button(self.panel, label='Browse') 
     browseBtn.Bind(wx.EVT_BUTTON, self.onBrowse) 

     self.mainSizer = wx.BoxSizer(wx.VERTICAL) 
     self.sizer = wx.BoxSizer(wx.HORIZONTAL) 

     self.mainSizer.Add(wx.StaticLine(self.panel, wx.ID_ANY), 
          0, wx.ALL|wx.EXPAND, 5) 
     self.mainSizer.Add(instructLbl, 0, wx.ALL, 5) 
     self.mainSizer.Add(self.imageCtrl, 0, wx.ALL, 5) 
     self.sizer.Add(self.photoTxt, 0, wx.ALL, 5) 
     self.sizer.Add(browseBtn, 0, wx.ALL, 5) 
     self.mainSizer.Add(self.sizer, 0, wx.ALL, 5) 

     self.panel.SetSizer(self.mainSizer) 
     self.mainSizer.Fit(self.frame) 

     self.panel.Layout() 

    def onBrowse(self, event): 
     """ 
     Browse for file 
     """ 
     wildcard = "JPEG files (*.jpg)|*.jpg" 
     dialog = wx.FileDialog(None, "Choose a file", 
           wildcard=wildcard, 
           style=wx.OPEN) 
     if dialog.ShowModal() == wx.ID_OK: 
      self.photoTxt.SetValue(dialog.GetPath()) 
     dialog.Destroy() 
     self.onView() 

    def update_image_on_dnd(self, filepath): 
     self.onView(filepath=filepath) 

    def onView(self, filepath=None): 
     if not filepath: 
      filepath = self.photoTxt.GetValue() 

     img = wx.Image(filepath, wx.BITMAP_TYPE_ANY) 
     # scale the image, preserving the aspect ratio 
     W = img.GetWidth() 
     H = img.GetHeight() 
     if W > H: 
      NewW = self.PhotoMaxSize 
      NewH = self.PhotoMaxSize * H/W 
     else: 
      NewH = self.PhotoMaxSize 
      NewW = self.PhotoMaxSize * W/H 
     img = img.Scale(NewW,NewH) 

     self.imageCtrl.SetBitmap(wx.Bitmap(img)) 
     self.panel.Refresh() 

if __name__ == '__main__': 
    app = PhotoCtrl() 
    app.MainLoop() 

Das ist für mich auf Windows 7 mit wxPython 4. Hinweis gearbeitet, dass ich eine Datei aus dem Windows Explorer am Ziehen auf meine WxPython Anwendung Bild-Widget.

+0

Vielen Dank! Das einzige Problem, das ich fand, war, dass der Aufruf von BitmapFromImage abgeschrieben wurde. (Ich glaube ich verwende die neueste Version von wxPython mit Python 3.6.3). –

+1

Ich dachte, ich hätte all die veralteten Sachen bekommen. Ich habe gerade den Code aktualisiert, um diese Warnungen zu beheben. –

+0

Sehr umfangreiche Antwort, verdient mehr Kredit als es bisher ist. – Montmons