在wxPython中跨面板拖放图像
发布时间:2020-12-20 13:33:16 所属栏目:Python 来源:网络整理
导读:我目前不确定如何跨面板实现一些对象(在本例中为png)的拖放.我已经查看了wx Python示例中提供的关联DragImage示例,这里的大部分代码都是从中派生出来的.但是,如果您运行下面的代码(您需要生成一个或两个示例PNG),我有三个面板:顶部的面板,我希望PNG连续加载
我目前不确定如何跨面板实现一些对象(在本例中为png)的拖放.我已经查看了wx
Python示例中提供的关联DragImage示例,这里的大部分代码都是从中派生出来的.但是,如果您运行下面的代码(您需要生成一个或两个示例PNG),我有三个面板:顶部的面板,我希望PNG连续加载,然后两个它下面的面板.将顶部面板上的PNG排成一行的代码行目前已被注释掉(在MechanismPanel类下面,它位于底部),因为它阻止我获取任何鼠标事件.我不确定是否可以在面板上拖放图像,或者是否可以,如果我正确地进行操作.
编辑:对我正在寻找的内容进行更为简洁的解释.顶部面板中的图像,您可以将其中一个图像拖出并将其添加到其中一个下面板.可以将顶部面板视为一系列要绘制的小部件,将底部的两个面板视为排列小部件的位置.为了帮助区分问题,我还有一个关于在顶部面板here中拖动和复制图像的问题. import os import glob import wx import wx.lib.scrolledpanel as scrolled class MainWindow(wx.Frame): def __init__(self,parent,title): wx.Frame.__init__(self,parent) frm_pnl = MainPanel(self) self.Show() class DragShape: def __init__(self,bmp): self.bmp = bmp self.pos = (0,0) self.shown = True self.text = None self.fullscreen = False def HitTest(self,pt): rect = self.GetRect() return rect.InsideXY(pt.x,pt.y) def GetRect(self): return wx.Rect(self.pos[0],self.pos[1],self.bmp.GetWidth(),self.bmp.GetHeight()) def Draw(self,dc,op = wx.COPY): if self.bmp.Ok(): memDC = wx.MemoryDC() memDC.SelectObject(self.bmp) dc.Blit(self.pos[0],self.bmp.GetHeight(),memDC,op,True) return True else: return False class MainPanel(wx.Panel): def __init__(self,parent): wx.Panel.__init__(self,-1,size = (900,700)) self.shapes = [] #panel for mechanisms mechPnl = MechanismPanel(self) mechSzr = wx.BoxSizer(wx.HORIZONTAL) mechSzr.Add(mechPnl,1) #panels for timeline posPnl = IdTimelinePanel(self) timelinePnl = TimelinePanel(self) mainSzr = wx.BoxSizer(wx.HORIZONTAL) mainSzr.Add(posPnl,1,wx.EXPAND) mainSzr.Add(timelinePnl,wx.EXPAND) selfSizer = wx.BoxSizer(wx.VERTICAL) selfSizer.Add(mechSzr,wx.EXPAND) selfSizer.Add(mainSzr,wx.EXPAND) selfSizer.Layout() self.SetSizer(selfSizer) self.dragImage = None self.dragShape = None self.hiliteShape = None self.SetCursor(wx.StockCursor(wx.CURSOR_ARROW)) #self.Bind(wx.EVT_ERASE_BACKGROUND,self.OnEraseBackground) self.Bind(wx.EVT_PAINT,self.OnPaint) mechPnl.Bind(wx.EVT_LEFT_DOWN,self.OnLeftDown) mechPnl.Bind(wx.EVT_LEFT_UP,self.OnLeftUp) mechPnl.Bind(wx.EVT_MOTION,self.OnMotion) mechPnl.Bind(wx.EVT_LEAVE_WINDOW,self.OnLeaveWindow) timelinePnl.Bind(wx.EVT_LEFT_DOWN,self.OnLeftDown) timelinePnl.Bind(wx.EVT_LEFT_UP,self.OnLeftUp) timelinePnl.Bind(wx.EVT_MOTION,self.OnMotion) timelinePnl.Bind(wx.EVT_LEAVE_WINDOW,self.OnLeaveWindow) # The mouse is moving def OnMotion(self,evt): print "On motion!" # Ignore mouse movement if we're not dragging. if not self.dragShape or not evt.Dragging() or not evt.LeftIsDown(): return # if we have a shape,but haven't started dragging yet if self.dragShape and not self.dragImage: # only start the drag after having moved a couple pixels tolerance = 2 pt = evt.GetPosition() dx = abs(pt.x - self.dragStartPos.x) dy = abs(pt.y - self.dragStartPos.y) if dx <= tolerance and dy <= tolerance: return # refresh the area of the window where the shape was so it # will get erased. self.dragShape.shown = False self.RefreshRect(self.dragShape.GetRect(),True) self.Update() if self.dragShape.text: self.dragImage = wx.DragString(self.dragShape.text,wx.StockCursor(wx.CURSOR_HAND)) else: self.dragImage = wx.DragImage(self.dragShape.bmp,wx.StockCursor(wx.CURSOR_HAND)) hotspot = self.dragStartPos - self.dragShape.pos self.dragImage.BeginDrag(hotspot,self,self.dragShape.fullscreen) self.dragImage.Move(pt) self.dragImage.Show() # if we have shape and image then move it,posibly highlighting another shape. elif self.dragShape and self.dragImage: onShape = self.FindShape(evt.GetPosition()) unhiliteOld = False hiliteNew = False # figure out what to hilite and what to unhilite if self.hiliteShape: if onShape is None or self.hiliteShape is not onShape: unhiliteOld = True if onShape and onShape is not self.hiliteShape and onShape.shown: hiliteNew = True # if needed,hide the drag image so we can update the window if unhiliteOld or hiliteNew: self.dragImage.Hide() if unhiliteOld: dc = wx.ClientDC(self) self.hiliteShape.Draw(dc) self.hiliteShape = None if hiliteNew: dc = wx.ClientDC(self) self.hiliteShape = onShape self.hiliteShape.Draw(dc,wx.INVERT) # now move it and show it again if needed self.dragImage.Move(evt.GetPosition()) if unhiliteOld or hiliteNew: self.dragImage.Show() # Left mouse button up. def OnLeftUp(self,evt): print "On left up!" if not self.dragImage or not self.dragShape: self.dragImage = None self.dragShape = None return # Hide the image,end dragging,and nuke out the drag image. self.dragImage.Hide() self.dragImage.EndDrag() self.dragImage = None if self.hiliteShape: self.RefreshRect(self.hiliteShape.GetRect()) self.hiliteShape = None # reposition and draw the shape # Note by jmg 11/28/03 # Here's the original: # # self.dragShape.pos = self.dragShape.pos + evt.GetPosition() - self.dragStartPos # # So if there are any problems associated with this,use that as # a starting place in your investigation. I've tried to simulate the # wx.Point __add__ method here -- it won't work for tuples as we # have now from the various methods # # There must be a better way to do this :-) # self.dragShape.pos = ( self.dragShape.pos[0] + evt.GetPosition()[0] - self.dragStartPos[0],self.dragShape.pos[1] + evt.GetPosition()[1] - self.dragStartPos[1] ) self.dragShape.shown = True self.RefreshRect(self.dragShape.GetRect()) self.dragShape = None # Fired whenever a paint event occurs def OnPaint(self,evt): print "On paint!" dc = wx.PaintDC(self) self.PrepareDC(dc) self.DrawShapes(dc) # Left mouse button is down. def OnLeftDown(self,evt): print "On left down!" # Did the mouse go down on one of our shapes? shape = self.FindShape(evt.GetPosition()) # If a shape was 'hit',then set that as the shape we're going to # drag around. Get our start position. Dragging has not yet started. # That will happen once the mouse moves,OR the mouse is released. if shape: self.dragShape = shape self.dragStartPos = evt.GetPosition() # Go through our list of shapes and draw them in whatever place they are. def DrawShapes(self,dc): for shape in self.shapes: if shape.shown: shape.Draw(dc) # This is actually a sophisticated 'hit test',but in this # case we're also determining which shape,if any,was 'hit'. def FindShape(self,pt): for shape in self.shapes: if shape.HitTest(pt): return shape return None # Clears the background,then redraws it. If the DC is passed,then # we only do so in the area so designated. Otherwise,it's the whole thing. def OnEraseBackground(self,evt): dc = evt.GetDC() if not dc: dc = wx.ClientDC(self) rect = self.GetUpdateRegion().GetBox() dc.SetClippingRect(rect) self.TileBackground(dc) # tile the background bitmap def TileBackground(self,dc): sz = self.GetClientSize() w = self.bg_bmp.GetWidth() h = self.bg_bmp.GetHeight() x = 0 while x < sz.width: y = 0 while y < sz.height: dc.DrawBitmap(self.bg_bmp,x,y) y = y + h x = x + w # We're not doing anything here,but you might have reason to. # for example,if you were dragging something,you might elect to # 'drop it' when the cursor left the window. def OnLeaveWindow(self,evt): pass class IdTimelinePanel(wx.Panel): def __init__(self,size = (400,200)) self.SetBackgroundColour((255,255)) lbl1 = wx.StaticText(self,label="Position") lbl2 = wx.StaticText(self,label="Size") posPnlSzr = wx.BoxSizer(wx.VERTICAL) posPnlSzr.Add(lbl1,wx.FIXED&wx.LEFT) posPnlSzr.Add(lbl2,wx.FIXED&wx.LEFT) self.SetSizer(posPnlSzr) #wx.StaticText(self,"This is the horizontal ID space for the timeline") self.SetAutoLayout(1) class TimelinePanel(scrolled.ScrolledPanel): def __init__(self,parent): scrolled.ScrolledPanel.__init__(self,size = (300,0)) lbl12 = wx.StaticText(self,label="Position") lbl22 = wx.StaticText(self,label="Size") posPnlSzr2 = wx.BoxSizer(wx.VERTICAL) posPnlSzr2.Add(lbl12,wx.GROW) posPnlSzr2.Add(lbl22,wx.GROW) self.SetSizer(posPnlSzr2) #wx.StaticText(self,"This is the horizontal scroll space for the timeline") self.SetAutoLayout(1) self.SetupScrolling(scroll_y = False) class MechanismPanel(scrolled.ScrolledPanel): def __init__(self,140)) self.SetBackgroundColour((211,211,211)) mechPnlSzr = wx.BoxSizer(wx.HORIZONTAL) os.chdir("./figures") for file in glob.glob("icon*.png"): print file imgIcon = wx.Image(file,wx.BITMAP_TYPE_PNG).ConvertToBitmap() staticBitmap = wx.StaticBitmap(self,imgIcon,(0,0),(50,50)) shape = DragShape(staticBitmap.GetBitmap()) shape.pos = (50,50) shape.fullscreen = True parent.shapes.append(shape) #mechPnlSzr.Add(staticBitmap,wx.FIXED,border = 20) self.SetSizer(mechPnlSzr) self.SetAutoLayout(1) self.SetupScrolling(scroll_y = False) app = wx.App(False) frame = MainWindow(None,"Trading Client") app.MainLoop() 解决方法
您的类都没有实现wx.PyDropTarget接口或包含对拖放所需的wx.FileDataObject()的引用.
我想你想看看演示中的DragAndDrop示例,而不仅仅是DragImage. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
相关内容
- Python编程实现生成特定范围内不重复多个随机数的2种方法
- Python中使用socket发送HTTP请求数据接收不完整问题解决方法
- python3 高级编程(二) 动态给类添加方法功能
- python中英文混合字符串对齐输出
- 资深程序员:深入Python进程间通信原理!
- python – 使用双端队列生成defaultdict的问题
- 并发 – 在RWMutex解锁后两次调用RWMutex RLock时的gorouti
- 如果列表长度未知(Python),如何识别列表中的所有数字是相同
- python – pandas.read_feather得到一个意外的参数nthreads
- python – 如何使用静态方法作为策略设计模式的默认参数?