• 19.04.2024, 23:48
  • Registrieren
  • Anmelden
  • Sie sind nicht angemeldet.

 

[wx.Python] Probleme beim Drag & Drop

Dienstag, 12. Januar 2010, 03:21

Hallöchen Liebe Leute

Ich hab folgendes Problem:

Ich soll einen Raumplaner gestallten auf dessen Raster man per Drag & Drop grafische Elemente ziehen kann. Das Raster hab ich schon allerdings macht mir das Drag & Droppen von den Bitmaps probleme, da ich nicht weiß, wie ich die Bitmaps bzw die Rechtecke dragbar mach.

Hier mal mein Code bis jetzt:

Klickt man auf Neu, so wird einem das Raster angezeigt.

Wäre nett wenn mir vielleicht jemand erklären könnte oder zeigen könnte wie ich das mache. THX

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
# coding=utf-8

import wx	# wxPython
import os	# OS-spezifische Funktionen
import  cPickle 

class DropTarget(wx.PyDropTarget):
   def __init__(self, parent):
  	wx.PyDropTarget.__init__(self)
  	
  	self.data = wx.PyBitmapDataObject()#wx.EmptyBitmap(width=100, height=100, depth = -1))
  	self.SetDataObject(self.data)
  	
   def OnDrop(self, x, y):
  	return True
   
   def OnData(self, x, y, d):
  	if self.GetData():
     	# convert it back to a list of lines and give it to the viewer
     	linesdata = self.data.GetData()
     	lines = cPickle.loads(linesdata)
     	self.dv.SetLines(lines)
     	
     	return d
  	
class DropSource(wx.Window):
   def __init__(self, parent):
  	wx.Window.__init__(self, parent, pos=(800, 0),size=(350,600), style=wx.SUNKEN_BORDER)
  	self.parent = parent
  	self.lines = [] 
  	
  	self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)

  	
  	pdc = wx.ClientDC(self)
  	pdc.SetBrush(wx.Brush('GREEN YELLOW'))
  	pdc.DrawRectangle(0, 0, 90, 160)
  	
   def OnLeftDown(self, event):
  	self.StartDragOpperation() 
        	
   def StartDragOpperation(self):   
        	
  	linesdata = cPickle.dumps(self.lines, 1)
  	
  	ldata = wx.CustomDataObject("DoodleLines")
  	ldata.SetData(linesdata)
  	
  	bmp1 = wx.EmptyBitmap(90, 160)
  	
  	dc = wx.MemoryDC()
  	dc.SelectObject(bmp1)
  	
  	bdata = wx.BitmapDataObject(bmp1)
  	data = wx.DataObjectComposite()
  	data.Add(ldata)
  	data.Add(bdata)
  	
  	dropSource = wx.DropSource(self)
  	dropSource.SetData(data)
  	
     	
class W1(wx.Window):
   def __init__(self, parent):
  	wx.Window.__init__(self, parent, pos=(0, 0), size=(90, 160), style=wx.SUNKEN_BORDER)
  	
  	dt = DropTarget(self)
  	self.SetDropTarget(dt)
  	
class W2(wx.Window):
   def __init__(self, parent):
  	wx.Window.__init__(self, parent, pos=(0, 290), size=(90, 160), style=wx.SUNKEN_BORDER)
  	
  	dt = DropTarget(self)
  	self.SetDropTarget(dt)   

class Zeichnen(wx.Window):
   def __init__(self, parent):
  	wx.Window.__init__(self, parent, pos=(10,20), size=(700,450), style=wx.SUNKEN_BORDER) 
  	#self.SetBackgroundColour(wx.WHITE)

  	dt = DropTarget(self)
  	
  	self.Bind(wx.EVT_PAINT, self.OnPaint) 
   	
   def OnPaint(self, event):
    	
  	point = [((95,0),(95,450)), #senkrechte linie links
           	((605,0),(605,450)), #senkrechte linie rechts
           	((0,165),(95,165)), #1. waagerechte
           	((0,285),(95,285)), #2. waagerechte
           	((605,165),(700,165)), #3. waagerechte
           	((605,285),(700,285)), #4.waagerechte
           	((155,165),(556,165)), #waagerechte 4er block oben
           	((155,285),(556,285)), #waagerechte 4er block unten
           	((155,0),(155,165)),   #senkrechte linien oben
           	((255,0),(255,165)),
           	((355,0),(355,165)),
           	((455,0),(455,165)),
           	((555,0),(555,165)),
           	((155,285),(155,450)),   #senkrechte linien unten
           	((255,285),(255,450)),
           	((355,285),(355,450)),
           	((455,285),(455,450)),
           	((555,285),(555,450))]
       	
  	dc = wx.PaintDC(self)
  	dc.BeginDrawing()
  	pen = wx.Pen('WHITE', 9, wx.SOLID)

  	for x in range(0,len(point)):
     	pen.SetCap(wx.CAP_ROUND)
     	dc.SetPen(pen)
     	dc.DrawLines(point[x])
  	
  	dc.SetBrush(wx.Brush('GREEN YELLOW', wx.BDIAGONAL_HATCH))

  	dc.SetPen(wx.Pen('WHITE', 1, wx.TRANSPARENT))
  	dc.DrawRectangle(96, 0, 59, 450)
  	dc.DrawRectangle(556, 0, 49, 450)
  	dc.DrawRectangle(155, 166, 401, 119)
    	
  	dc.SetBrush(wx.Brush('GREEN YELLOW'))
    	
  	dc.DrawRectangle(0, 0, 90, 160)
  	dc.DrawRectangle(0, 170, 90, 110)
  	dc.DrawRectangle(0, 290, 90, 160)
      	
  	k = 0 
  	for j in range(4):
     	dc.DrawRectangle(160+k, 0, 90, 160)
     	k = k + 100 
   	
  	k = 0 
  	for j in range(4):
     	dc.DrawRectangle(160+k, 290, 90, 160)
     	k = k + 100
   	
  	dc.DrawRectangle(610, 0, 90, 160)
  	dc.DrawRectangle(610, 170, 90, 110)
  	dc.DrawRectangle(610, 290, 90, 160)

  	dc.EndDrawing() 

class Raum(wx.Frame):
	#------------------------------------------------------------------------------
   def __init__(self):
  	wx.Frame.__init__(self, None, -1,"Raumplaner", (200,300), (1200,600))
  	self.panel = wx.Panel(self, -1, style=wx.SIMPLE_BORDER)
              	
  	vbox = wx.BoxSizer(wx.VERTICAL) 
  	sizer = wx.BoxSizer(wx.VERTICAL)
                          	
  	#Erstellen der Toolbar
  	self.toolbar = wx.ToolBar(self, -1, style=wx.NO_BORDER)#style=wx.TB_HORIZONTAL | wx.NO_BORDER)
  	self.toolbar.SetToolBitmapSize((32,32))
  	self.toolbar.AddLabelTool( 0, 'Neu', wx.Bitmap('./icons/new_page.png'), wx.NullBitmap , wx.ITEM_NORMAL, 'Neu', 'Neues Element', None)
  	self.toolbar.AddLabelTool( 1, u'Öffnen', wx.Bitmap('./icons/open.png'), wx.NullBitmap , wx.ITEM_NORMAL, u'Öffnen', u'Datei öffnen', None)
  	self.toolbar.AddLabelTool( 2, 'Speichern als', wx.Bitmap('./icons/save_as.png'), wx.NullBitmap , wx.ITEM_NORMAL, 'Speichern als', 'Speichern als', None)
  	self.toolbar.AddLabelTool( 3, 'Beenden', wx.Bitmap('./icons/exit.png'), wx.NullBitmap , wx.ITEM_NORMAL, 'Beenden', 'Beenden', None)
  	self.toolbar.Realize()  

  	sizer.Add(self.toolbar, 0, wx.EXPAND | wx.ALL | wx.TOP)

  	vbox.Add(sizer)
  	vbox.Add(self.panel, 1, wx.EXPAND | wx.ALL, 0)

  	self.SetSize((1200, 600))
  	self.SetSizer(vbox)
  	
  	#Erstellen der Statusbar
  	self.statusbar = self.CreateStatusBar(2)
  	self.SetStatusBar(self.statusbar)
  	
  	self.toolbar.Bind(wx.EVT_TOOL, self.OnNew, id = 0)
  	self.toolbar.Bind(wx.EVT_TOOL, self.OnOpen, id = 1)
  	#self.toolbar.Bind(wx.EVT_TOOL, self.OnSaveAs, id = 2)
  	self.toolbar.Bind(wx.EVT_TOOL, self.OnExit, id = 3)
  	
  	#Erstellen der Menübar
  	self.menubar = wx.MenuBar()
  	datei = wx.Menu() 
  	work = wx.Menu()
  	
  	self.new = wx.MenuItem(datei, 000, '&Neue Etage\tCtrl+N', 'Neue Datei erstellen') 
  	self.open = wx.MenuItem(datei, 001, u'&Öffnen\tCtrl+O', u'Datei öffnen')
  	self.worked = wx.MenuItem(datei, 002, 'B&earbeiten\tCtrl+B', 'Datei bearbeiten')
  	self.save = wx.MenuItem(datei, 003, '&Speichern\tCtrl+S', 'Datei speichern')
  	self.quit = wx.MenuItem(datei, 004, '&Beenden\tCtrl+Q', 'Programm Beenden')
  	
  	self.back = wx.MenuItem(work, 010, '&Neue Etage\tCtrl+N', 'Neue Datei erstellen') 
  	self.delete = wx.MenuItem(work, 011, u'&Öffnen\tCtrl+O', u'Datei öffnen')
  	self.test = wx.MenuItem(work, 012, 'B&earbeiten\tCtrl+B', 'Datei bearbeiten')
	
  	datei.AppendItem(self.new)
  	datei.AppendItem(self.open)
  	datei.AppendSeparator()   
  	datei.AppendItem(self.worked)
  	self.worked.Enable(False)
  	datei.AppendItem(self.save)
  	self.save.Enable(False)
  	datei.AppendSeparator()
  	datei.AppendItem(self.quit)
  	
  	work.AppendItem(self.back)
  	work.AppendItem(self.delete)
  	work.AppendItem(self.test)
	
  	self.Bind(wx.EVT_MENU, self.OnNew, id = 0)
  	self.Bind(wx.EVT_MENU, self.OnOpen, id = 1)
  	#self.Bind(wx.EVT_MENU, self.OnWorked, id = 2)
  	#self.Bind(wx.EVT_MENU, self.OnSaveAs, id = 3)
  	self.Bind(wx.EVT_MENU, self.OnExit, id = 004)

  	self.menubar.Append(datei, '&Datei')
  	self.menubar.Append(work, '&Bearbeiten')
  	self.SetMenuBar(self.menubar)
                                 	
   def OnNew(self, event):  	
  	
  	self.w1 = W1(Zeichnen(self.panel))
  	self.source = DropSource(self.panel)
                                   	
  	self.Centre() 
  	self.Show(True)
	
  	self.worked.Enable(True)
  	self.save.Enable(True)
  	self.menubar.Refresh()
  	
   def OnOpen(self, event):
  	self.directory = os.getcwd()
	
  	self.save = wx.FileDialog(self, u'Bitte Datei zum Laden wählen', self.directory, '', '*.txt', wx.FD_OPEN | wx.FD_CHANGE_DIR)
	
  	self.choose_save = self.save.ShowModal()
  	
  	if self.choose_save == wx.ID_OK:
     	try:
        	wx.MessageBox("Speichervorgang erfolgreich!", "Info", wx.OK | wx.ICON_INFORMATION)
     	except IOError, error:
        	wx.MessageBox("Fehler:\n" + str(error), "Info", wx.OK | wx.ICON_INFORMATION)
	
   #def OnWorked(self, event):
  	#self.dc1.Clear()
	
 #def OnSaveAs(self, event):
	#self.Close()
 
   def OnExit(self, event):
  	
  	self.Close()
        	
if __name__ == '__main__':
   
   app = wx.PySimpleApp()
   Raum().Show()
   app.MainLoop()

Dienstag, 12. Januar 2010, 19:54

Hast du dir mal die Demo-Applikation angesehen, die wxPython mitbringt? Da ist mindestens ein Beispiel einschließlich Code dabei, das D'n'D (innerhalb eines Grafikpanes) demonstriert.

Dienstag, 12. Januar 2010, 21:16

meinst du des CustomDnD? oder welche Demo explizit?

Dienstag, 12. Januar 2010, 23:04

Ich habe die nicht vor Augen oder zur Hand, aber da war definitiv mal was dabei in der Richtung.

Mittwoch, 13. Januar 2010, 03:52

weißt du denn ob es möglich ist in wx.python ein rechteck zu zeichnen, welches ich per drag & drop verschieben kann. oder muss ich dafür per photoshop nen rechteck zeichnen?

Mittwoch, 13. Januar 2010, 20:45

Irgendeine 2D-Pane wird es bestimmt geben. Aber auch das sollte die Demo zeigen.

Ansonsten: python-forum.de ist eine sehr gute Anlaufstelle für derlei Fragen.

Mittwoch, 13. Januar 2010, 21:04

http://wiki.wxpython.org/DragAndDrop

hilft dir nicht weiter oder?
i5 2500k | MSI-P67A-GD55 | HD6950 @ 6970 | Intel SSD 80GB G2 | Samsung F3 1TB & Samsung F4 2TB | 8GB G.Skill

Donnerstag, 14. Januar 2010, 06:25

soo habs jetzt fast allerdings hab ich noch nen Problem mit meinem DropTarget. Ich krieg es nicht hin, dass das gezogene Rechteck dort wieder angezeigt wird.

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# coding=utf-8

import wx	# wxPython
import os	# OS-spezifische Funktionen
import cPickle 

class DropTarget(wx.PyDropTarget):
   def __init__(self, parent):
  	wx.PyDropTarget.__init__(self)
        	
  	self.data = wx.CustomDataObject("DoodleLines")
  	self.SetDataObject(self.data) 
        	
   def OnDrop(self, x, y):
  	return True
   
   def OnData(self, x, y, d):
     	
  	return d
   
class Room_draw(object):
#--------------------------------------

   def __init__(self, room_name, size):
   #-----------------------------------
  	self.name_room = room_name
  	self.size = size
  	self.pos  = (0,0)
  	self.status = 0

   def SetPosition(self, pos):
   #-----------------------------------
  	self.pos = pos

   #Zeichnen der Räume für die Belegung
   def Draw_Room(self, dc):
   #-----------------------------------
  	if self.status == 1:
     	actPen_o = dc.GetPen()
     	dc.SetPen(wx.Pen('black', 5, wx.SOLID))

  	dc.DrawRectangle(self.pos[0], self.pos[1], self.size[0], self.size[1])
  	dc.DrawText(self.name_room, self.pos[0], self.pos[1])

  	if self.status == 1:
     	dc.SetPen(actPen_o)

   #Prüfen ob Raum ausgewählt
   def HitTest(self, x_pos, y_pos):
   #-----------------------------------
  	if x_pos > self.pos[0] and x_pos < (self.pos[0] + self.size[0]):
     	if y_pos > self.pos[1] and y_pos < (self.pos[1] + self.size[1]):
        	return True

  	return False

   def Select_Room(self):
   #-----------------------------------
  	self.status = 1

   def DeSelect_Room(self):
   #-----------------------------------
  	self.status = 0
        	
class DropSource(wx.Window):
   def __init__(self, parent_opl):
   #-----------------------------------
  	wx.Window.__init__(self, parent_opl, size=(300,400), pos=(800,50))

  	self.Bind(wx.EVT_PAINT, self.OnPaint)
  	self.Bind(wx.EVT_SIZE, self.OnSize)
  	self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
  	self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)

  	self.rooms_list = [Room_draw('W1', (90, 160)), Room_draw('W2', (90, 110))]
  	
  	#Position der Räume festlegen
  	x_pos = 100
  	y_pos = 100
  	for room_each in self.rooms_list:
     	room_each.SetPosition((x_pos, y_pos))
     	x_pos = x_pos + 100

  	self.dragRoom_o = None

   def OnPaint(self, event):
   #-----------------------------------
  	dc = wx.PaintDC(self)

  	dc.SetPen(wx.Pen('black', 1, wx.SOLID))
  	font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT)
  	dc.SetFont(font)

  	# alle Räume darstellen
  	for room_each in self.rooms_list:
     	room_each.Draw_Room(dc)

   def OnSize(self, event):
   #-----------------------------------
  	size = self.GetParent().GetClientSize()
  	self.SetSize(size)

   def OnLeftDown(self, event):
   #-----------------------------------
  	# wurde ein Rechteck getroffen ?
  	x_pos = event.GetX()
  	y_pos = event.GetY()

  	for room_each in self.rooms_list:
     	if room_each.HitTest(x_pos, y_pos):
        	room_each.Select_Room()
        	self.dragRoom_one = room_each
     	else:
        	room_each.DeSelect_Room()
        	
  	linesdata = cPickle.dumps(room_each, 1)
        	
  	bdata = wx.CustomDataObject("DoodleLines")
  	bdata.SetData(linesdata)
  	
  	dropSource = wx.DropSource(self)
  	dropSource.SetData(bdata)
  	
  	dropSource.DoDragDrop(wx.Drag_AllowMove)

  	# neu darstellen
  	self.Refresh()

   def OnLeftUp(self, event):
   #-----------------------------------
  	if self.dragRoom_one != None:
     	# Ziehen beenden
     	self.dragRoom_one = None
     	self.Refresh()
 	
class W1(wx.Window):
   def __init__(self, parent):
  	wx.Window.__init__(self, parent, pos=(0, 0), size=(90, 160), style=wx.SUNKEN_BORDER)
  	
  	dt = DropTarget(self)
  	self.SetDropTarget(dt)

Ähnliche Themen