Size: 9703
Comment:
|
Size: 9939
Comment:
|
Deletions are marked like this. | Additions are marked like this. |
Line 18: | Line 18: |
Here's how you can use drag-and-drop to reorder a simple list, or to move items from one list to another. As it stands, item data will be lost. Maybe in version 2 ! |
Here's how you can use drag-and-drop to reorder a simple list, or to move items from one list to another. As it stands, item data will be lost. Maybe in version 2 ! |
Line 23: | Line 22: |
Line 24: | Line 24: |
Line 29: | Line 30: |
Line 30: | Line 32: |
Line 34: | Line 37: |
Line 38: | Line 42: |
#--------------------------------------------------------------------------- | #--------------------------------------------------------------------------- |
Line 40: | Line 46: |
#--------------------------------------------------------------------------- |
#--------------------------------------------------------------------------- |
Line 48: | Line 54: |
#------------ | #------------ |
Line 52: | Line 59: |
#------------ | #------------ |
Line 54: | Line 63: |
dl1.SetBackgroundColour("#e6ffd0") | dl1.SetBackgroundColour("#e6ffd0") |
Line 60: | Line 70: |
Line 62: | Line 72: |
Line 67: | Line 78: |
#------------ |
#------------ |
Line 71: | Line 82: |
Line 73: | Line 85: |
Line 76: | Line 88: |
#--------------------------------------------------------------------------- | #--------------------------------------------------------------------------- |
Line 80: | Line 94: |
#------------ | #------------ |
Line 83: | Line 98: |
#------------ | #------------ |
Line 87: | Line 103: |
Line 88: | Line 105: |
Line 93: | Line 110: |
Line 101: | Line 118: |
Line 105: | Line 124: |
Line 113: | Line 132: |
Line 115: | Line 135: |
# Create our own data format and use it | # Create our own data format and use it |
Line 122: | Line 142: |
Line 126: | Line 147: |
Line 130: | Line 152: |
Line 135: | Line 158: |
Line 139: | Line 164: |
Line 141: | Line 167: |
Line 152: | Line 179: |
Line 157: | Line 185: |
Line 166: | Line 195: |
#--------------------------------------------------------------------------- | #--------------------------------------------------------------------------- |
Line 177: | Line 208: |
#------------ | #------------ |
Line 180: | Line 212: |
#------------ | #------------ |
Line 185: | Line 218: |
Line 186: | Line 220: |
# Called when OnDrop returns True. |
# Called when OnDrop returns True. |
Line 193: | Line 227: |
Line 200: | Line 234: |
Line 204: | Line 239: |
#--------------------------------------------------------------------------- class MyApp(wx.App): |
#--------------------------------------------------------------------------- class MyApp(wx.App): |
Line 207: | Line 244: |
#------------ | #------------ |
Line 211: | Line 250: |
Line 212: | Line 252: |
#--------------------------------------------------------------------------- |
#--------------------------------------------------------------------------- |
Line 217: | Line 258: |
#--------------------------------------------------------------------------- | #--------------------------------------------------------------------------- |
List control and drag and drop - DnD (Phoenix)
Keywords : ListCtrl, Drag and drop.
Contents
Demonstrating :
Tested py3.x, wx4.x and Win10.
Are you ready to use some samples ?
Test, modify, correct, complete, improve and share your discoveries !
Sample one
Here's how you can use drag-and-drop to reorder a simple list, or to move items from one list to another. As it stands, item data will be lost. Maybe in version 2 !
1 # sample_one.py
2
3 """
4
5 Drag and drop (DnD) demo with listctrl :
6 - Dragging of multiple selected items.
7 - Dropping on an empty list.
8 - Dropping of items on a list with a different number of columns.
9 - Dropping on a different applications.
10
11 """
12
13 import pickle
14 import sys
15 from random import choice
16 import wx
17
18 # class MyFrame
19 # class MyDragList
20 # class MyListDrop
21 # class MyApp
22
23 #---------------------------------------------------------------------------
24
25 items = ['Foo', 'Bar', 'Baz', 'Zif', 'Zaf', 'Zof']
26
27 #---------------------------------------------------------------------------
28
29 class MyFrame(wx.Frame):
30 def __init__(self, parent, id):
31 wx.Frame.__init__(self, parent, id,
32 "Sample one",
33 size=(450, 295))
34
35 #------------
36
37 self.SetIcon(wx.Icon('wxwin.ico'))
38 self.SetMinSize((450, 295))
39
40 #------------
41
42 dl1 = MyDragList(self, style=wx.LC_LIST)
43 dl1.SetBackgroundColour("#e6ffd0")
44
45 dl2 = MyDragList(self, style=wx.LC_REPORT)
46 dl2.InsertColumn(0, "Column - 0", wx.LIST_FORMAT_LEFT)
47 dl2.InsertColumn(1, "Column - 1", wx.LIST_FORMAT_LEFT)
48 dl2.InsertColumn(2, "Column - 2", wx.LIST_FORMAT_LEFT)
49 dl2.SetBackgroundColour("#f0f0f0")
50
51 maxs = -sys.maxsize - 1
52
53 for item in items:
54 dl1.InsertItem(maxs, item)
55 idx = dl2.InsertItem(maxs, item)
56 dl2.SetItem(idx, 1, choice(items))
57 dl2.SetItem(idx, 2, choice(items))
58
59 #------------
60
61 sizer = wx.BoxSizer(wx.HORIZONTAL)
62
63 sizer.Add(dl1, proportion=1, flag=wx.EXPAND)
64 sizer.Add(dl2, proportion=1, flag=wx.EXPAND)
65
66 self.SetSizer(sizer)
67 self.Layout()
68
69 #---------------------------------------------------------------------------
70
71 class MyDragList(wx.ListCtrl):
72 def __init__(self, *arg, **kw):
73 wx.ListCtrl.__init__(self, *arg, **kw)
74
75 #------------
76
77 self.Bind(wx.EVT_LIST_BEGIN_DRAG, self.StartDrag)
78
79 #------------
80
81 dt = MyListDrop(self)
82 self.SetDropTarget(dt)
83
84 #-----------------------------------------------------------------------
85
86 def GetItemInfo(self, idx):
87 """
88 Collect all relevant data of a listitem, and put it in a list.
89 """
90
91 l = []
92 l.append(idx) # We need the original index, so it is easier to eventualy delete it.
93 l.append(self.GetItemData(idx)) # Itemdata.
94 l.append(self.GetItemText(idx)) # Text first column.
95 for i in range(1, self.GetColumnCount()): # Possible extra columns.
96 l.append(self.GetItem(idx, i).GetText())
97 return l
98
99
100 def StartDrag(self, event):
101 """
102 Put together a data object for drag-and-drop _from_ this list.
103 """
104
105 l = []
106 idx = -1
107 while True: # Find all the selected items and put them in a list.
108 idx = self.GetNextItem(idx, wx.LIST_NEXT_ALL, wx.LIST_STATE_SELECTED)
109 if idx == -1:
110 break
111 l.append(self.GetItemInfo(idx))
112
113 # Pickle the items list.
114 itemdata = pickle.dumps(l, 1)
115 # Create our own data format and use it
116 # in a Custom data object.
117 ldata = wx.CustomDataObject("ListCtrlItems")
118 ldata.SetData(itemdata)
119 # Now make a data object for the item list.
120 data = wx.DataObjectComposite()
121 data.Add(ldata)
122
123 # Create drop source and begin drag-and-drop.
124 dropSource = wx.DropSource(self)
125 dropSource.SetData(data)
126 res = dropSource.DoDragDrop(flags=wx.Drag_DefaultMove)
127
128 # If move, we want to remove the item from this list.
129 if res == wx.DragMove:
130 # It's possible we are dragging/dropping from this list to this list.
131 # In which case, the index we are removing may have changed...
132
133 # Find correct position.
134 l.reverse() # Delete all the items, starting with the last item.
135 for i in l:
136 pos = self.FindItem(i[0], i[2])
137 self.DeleteItem(pos)
138
139
140 def Insert(self, x, y, seq):
141 """
142 Insert text at given x, y coordinates --- used with drag-and-drop.
143 """
144
145 # Find insertion point.
146 index, flags = self.HitTest((x, y))
147
148 if index == wx.NOT_FOUND: # Not clicked on an item.
149 if flags & (wx.LIST_HITTEST_NOWHERE|wx.LIST_HITTEST_ABOVE|wx.LIST_HITTEST_BELOW): # Empty list or below last item.
150 index = self.GetItemCount() # Append to end of list.
151 elif self.GetItemCount() > 0:
152 if y <= self.GetItemRect(0).y: # Clicked just above first item.
153 index = 0 # Append to top of list.
154 else:
155 index = self.GetItemCount() + 1 # Append to end of list.
156 else: # Clicked on an item.
157 # Get bounding rectangle for the item the user is dropping over.
158 rect = self.GetItemRect(index)
159
160 # If the user is dropping into the lower half of the rect,
161 # we want to insert _after_ this item.
162 # Correct for the fact that there may be a heading involved.
163 if y > rect.y - self.GetItemRect(0).y + rect.height/2:
164 index += 1
165
166 for i in seq: # Insert the item data.
167 idx = self.InsertItem(index, i[2])
168 self.SetItemData(idx, i[1])
169 for j in range(1, self.GetColumnCount()):
170 try: # Target list can have more columns than source.
171 self.SetItem(idx, j, i[2+j])
172 except:
173 pass # Ignore the extra columns.
174 index += 1
175
176 #---------------------------------------------------------------------------
177
178 class MyListDrop(wx.DropTarget):
179 """
180 Drop target for simple lists.
181 """
182 def __init__(self, source):
183 """
184 Arguments:
185 source: source listctrl.
186 """
187 wx.DropTarget.__init__(self)
188
189 #------------
190
191 self.dv = source
192
193 #------------
194
195 # Specify the type of data we will accept.
196 self.data = wx.CustomDataObject("ListCtrlItems")
197 self.SetDataObject(self.data)
198
199 #-----------------------------------------------------------------------
200
201 # Called when OnDrop returns True.
202 # We need to get the data and do something with it.
203 def OnData(self, x, y, d):
204 """
205 ...
206 """
207
208 # Copy the data from the drag source to our data object.
209 if self.GetData():
210 # Convert it back to a list and give it to the viewer.
211 ldata = self.data.GetData()
212 l = pickle.loads(ldata)
213 self.dv.Insert(x, y, l)
214
215 # What is returned signals the source what to do
216 # with the original data (move, copy, etc.) In this
217 # case we just return the suggested value given to us.
218 return d
219
220 #---------------------------------------------------------------------------
221
222 class MyApp(wx.App):
223 def OnInit(self):
224
225 #------------
226
227 frame = MyFrame(parent=None, id=-1)
228 self.SetTopWindow(frame)
229 frame.Show(True)
230
231 return True
232
233 #---------------------------------------------------------------------------
234
235 def main():
236 app = MyApp(False)
237 app.MainLoop()
238
239 #---------------------------------------------------------------------------
240
241 if __name__ == "__main__" :
242 main()
Sample two
1 # sample_two.py
Download source
Additional Information
Link :
https://wiki.wxpython.org/List%20control%20and%20SQLite%20database%20%28Phoenix%29
https://wiki.wxpython.org/List%20control%20virtual%20%28Phoenix%29
https://wiki.wxpython.org/List%20control%20virtual%20and%20SQLite%20database%20%28Phoenix%29
http://jak-o-shadows.users.sourceforge.net/python/wxpy/dblistctrl.html
http://wxpython-users.1045709.n5.nabble.com/Example-of-Database-Interaction-td2361801.html
http://www.kitebird.com/articles/pydbapi.html
https://www.pgadmin.org/download/
https://github.com/1966bc/pyggybank
https://sourceforge.net/projects/pyggybank/
- - - - -
https://wiki.wxpython.org/TitleIndex
Thanks to
JohnFouhy (sample_one.py coding), ??? (sample_two.py coding) and the wxPython community...
About this page
Date(d/m/y) Person (bot) Comments :
14/03/20 - Ecco (Created page and updated examples for wxPython Phoenix).
Comments
- blah, blah, blah...