Hello!
I am trying to write a program with that I can assign images to
Products.
I have an imagelist that contains some images.
Via Drag and Drop, I transfer the selected image name into a text
field.
After the drag operation I want the image to be deleted from the
imagelist. For that I use the function: deleteFirstItemFromImageList()
After deleting, I refresh the image list. For that I use the function:
assignTextsAndShowImageList()
My Problem:
When I drag the image to the target text field: the OnDropText() is
carried out twice!
This leads to: the first and the second image name is inserted into
the text field. And the first and second image is deleted from the
imagelist!
Note 1:
This problem occurs on Windows.
When I run the program on Linux (ubuntu) the OnDropText() is only
carried out once (as expected).
Note 2:
When I (on Windows) run the function assignTextsAndShowImageList_1()
instead, then the OnDropText() is only carried out once (as
expected).
But this function does not refresh the imagelist correctly
Note 3:
I have created a button that does the same thing (call
deleteFirstItemFromImageList() and assignTextsAndShowImageList()).
The button works perfectly on Windows and Ubuntu.
Has anyone got an idea?
Here the complete code. In order to run it, you need a folder named
"bilder" with some images in the same directory...
···
#
--------------------------------------------------------------------------------------
###
#Boa:Frame:Frame1
import wx
import glob
# Define Text Drop Target class
class TextDropTarget(wx.TextDropTarget):
def __init__(self, obj):
wx.TextDropTarget.__init__(self)
self.obj = obj
def OnDropText(self, x, y, data):
# When text is dropped, write it into the object specified
self.obj.WriteText(data + '\n\n')
# and remove the item from the image list
deleteFirstItemFromImageList(self.self_frame1)
assignTextsAndShowImageList(self.self_frame1) # if this
function is called, OnDropText is carried twice!
#assignTextsAndShowImageList_1(self.self_frame1) # if this
function is called, OnDropText is only carried out once
#
-----------------------------------------------------------------------------------
def create(parent):
return Frame1(parent)
[wxID_FRAME1, wxID_FRAME1BTN_LOAD, wxID_FRAME1BUTTON1,
wxID_FRAME1LISTCTRL1,
wxID_FRAME1PANEL1, wxID_FRAME1STATICTEXT1, wxID_FRAME1TEXTCTRL1,
] = [wx.NewId() for _init_ctrls in range(7)]
class Frame1(wx.Frame):
def _init_ctrls(self, prnt):
# generated method, don't edit
wx.Frame.__init__(self, id=wxID_FRAME1, name='Frame1',
parent=prnt,
pos=wx.Point(366, 66), size=wx.Size(618, 466),
style=wx.DEFAULT_FRAME_STYLE, title='Bildertool')
self.SetClientSize(wx.Size(610, 439))
self.Bind(wx.EVT_CLOSE, self.OnFrame1Close)
self.panel1 = wx.Panel(id=wxID_FRAME1PANEL1, name='panel1',
parent=self,
pos=wx.Point(0, 0), size=wx.Size(610, 439),
style=wx.TAB_TRAVERSAL)
self.listCtrl1 = wx.ListCtrl(id=wxID_FRAME1LISTCTRL1,
name='listCtrl1',
parent=self.panel1, pos=wx.Point(48, 48),
size=wx.Size(424, 352),
style=wx.LC_ICON)
self.listCtrl1.Bind(wx.EVT_LIST_ITEM_SELECTED,
self.OnListCtrl1ListItemSelected,
id=wxID_FRAME1LISTCTRL1)
self.staticText1 = wx.StaticText(id=wxID_FRAME1STATICTEXT1,
label='Drop Target:', name='staticText1',
parent=self.panel1,
pos=wx.Point(47, 14), size=wx.Size(89, 18), style=0)
self.staticText1.SetToolTipString('')
self.btn_load = wx.Button(id=wxID_FRAME1BTN_LOAD, label='load
images',
name='btn_load', parent=self.panel1, pos=wx.Point(496,
84),
size=wx.Size(100, 23), style=0)
self.btn_load.Bind(wx.EVT_BUTTON, self.OnBtn_loadButton,
id=wxID_FRAME1BTN_LOAD)
self.textCtrl1 = wx.TextCtrl(id=wxID_FRAME1TEXTCTRL1,
name='textCtrl1',
parent=self.panel1, pos=wx.Point(140, 12),
size=wx.Size(220, 21),
style=0, value='')
self.button1 = wx.Button(id=wxID_FRAME1BUTTON1,
label='delete first item', name='button1',
parent=self.panel1,
pos=wx.Point(496, 120), size=wx.Size(100, 23), style=0)
self.button1.Bind(wx.EVT_BUTTON, self.OnButton1Button,
id=wxID_FRAME1BUTTON1)
def __init__(self, parent):
self._init_ctrls(parent)
# Create a Text Drop Target object
dt1 = TextDropTarget(self.textCtrl1)
# Link the Drop Target Object to the Text Control
self.textCtrl1.SetDropTarget(dt1)
TextDropTarget.self_frame1 = self # slightly unelegant
way. I want to refer to
# objects in "Frame1"
def OnBtn_loadButton(self, event):
# Bilder vom angegebenen Pfad laden
self.il = wx.ImageList(100, 100, True)
self.names = []
wx.InitAllImageHandlers()
for name in glob.glob("bilder/*"):
image = wx.Image(name, wx.BITMAP_TYPE_ANY)
width = image.GetWidth()
height = image.GetHeight()
thumbnail_size = 100
if width < height:
thumbnail_width = thumbnail_size
factor = width / thumbnail_size
thumbnail_height = height / factor
else:
thumbnail_height = thumbnail_size
factor = height / thumbnail_size
thumbnail_width = width / factor
image = image.Rescale(thumbnail_width, thumbnail_height)
bmp = wx.BitmapFromImage(image, depth = -1)
self.names.append(name)
self.il_max = self.il.Add(bmp)
assignTextsAndShowImageList(self)
def OnListCtrl1ListItemSelected(self, event):
""" Begin a Drag Operation """
itemSelected = event.GetItem()
dragText = itemSelected.GetText()
tdo = wx.PyTextDataObject(dragText)
tds = wx.DropSource(self.listCtrl1)
tds.SetData(tdo)
tds.DoDragDrop(True)
def OnButton1Button(self, event):
deleteFirstItemFromImageList(self)
assignTextsAndShowImageList(self)
def OnFrame1Close(self, event):
self.Destroy()
#
-------------------------------------------------------------------------
def assignTextsAndShowImageList(self):
self.listCtrl1.ClearAll()
il_max = self.il.GetImageCount()
self.listCtrl1.SetImageList(self.il, wx.IMAGE_LIST_NORMAL)
for x in range(il_max):
self.listCtrl1.InsertImageStringItem(x, self.names[x], x)
def assignTextsAndShowImageList_1(self):
# this function only refreshes the images, but the filenames
remain...
self.listCtrl1.Refresh()
def deleteFirstItemFromImageList(self):
self.il.Remove(0)
del self.names[0]
#
-------------------------------------------------------------------------
class BoaApp(wx.App):
def OnInit(self):
self.main = create(None)
self.main.Show()
self.SetTopWindow(self.main)
return True
def main():
application = BoaApp(0)
application.MainLoop()
if __name__ == '__main__':
main()
#
--------------------------------------------------------------------------------------
###
My versions:
Python: 2.7.2
WxPython:2.8.12.1
Many thanks,
Leon