试图在wXPython中制作滚动窗口的可拖动子项

时间:2012-02-27 15:34:46

标签: python scroll wxpython draggable children

我正在尝试创建其父级是ScrolledWindow并拦截鼠标拖动的子级,以允许在父级的客户区域内重新定位子级。我希望客户端虚拟滚动区域根据需要进行扩展以适应子项的位置(因此滚动的窗口图大于滚动)。拖动似乎是有问题的,因为它想要一直移动角落试图向左或向上拖动对象是有问题的。当小部件超出当前窗口边界时,它也不会滚动。在使用此代码的驱动程序中,所有ConceptNode小部件都将SemNetWidget指定为其父级。我不使用sizer,因为应保持孩子的绝对定位(拖动位置)。我不认为wxPython提供了一种通过中心而不是角落来定位对象的方法,因为它可以使一些更容易编码:

class SemNetWidget(wx.ScrolledWindow):
    def __init__(self,edit,*args,**kwargs):
        self.editor=edit
        super(SemNetWidget,self).__init__(*args,**kwargs)
        self.SetScrollbars(1,1,1,1)

class ConceptNode(wx.StaticText):
    count=0
    def __init__(self,nm,*args,**kwargs):
        if not kwargs.has_key("style"):
            kwargs["style"]=0
        kwargs["style"]=wx.SIMPLE_BORDER|wx.ALIGN_CENTRE
        super(ConceptNode,self).__init__(*args,**kwargs)
        par=args[0]
        self.nm=nm
        self.mcap=False
        self.par=par
        self.SetLabel(" %s " % self.nm)
        self.Move((0,15*self.count)) # so new nodes don't overlap
        self.par.FitInside()
        self.Bind(wx.EVT_MOUSE_EVENTS,self.onDrag) 
        self.Bind(wx.EVT_MOTION,self.onDrag)
        self.Bind(wx.EVT_MOUSE_CAPTURE_LOST,self.onUncap) 
        ConceptNode.count+=1
    def onUncap(self,evt):
        self.mcap=False
        self.drag=None
    def onDrag(self,evt):
        if evt.Dragging() and self.drag is not None:
            #cdc=wx.ClientDC(self)
            #self.PrepareDC(cdc)
            #pos=list(evt.GetLogicalPosition(cdc))
            pos=evt.GetPosition()
            dx=pos[0]-self.drag['x']
            dy=pos[1]-self.drag['y']
            self.SetPosition((self.drag['ox']+dx,
                              self.drag['oy']+dy),
                            wx.SIZE_ALLOW_MINUS_ONE)
        if evt.LeftDown():
            pos=evt.GetPosition()
            opos=self.GetPosition()
            self.drag={'x':pos[0],'y':pos[1],
                       'ox':opos[0],'oy':opos[1]}
            self.CaptureMouse()
            self.mcap=True
            evt.Skip()
        if evt.LeftUp():
            self.drag=None
            if self.mcap:
                self.ReleaseMouse()

驱动:

if __name__=="__main__":
    app=wx.App()
    window=wx.Frame(None,wx.ID_ANY)
    frame=SemNetWidget(None,window) # None:=No editor object
    c1=ConceptNode("Concept1",frame)
    c2=ConceptNode("Concept2",frame)
    window.Show()
    app.MainLoop()

1 个答案:

答案 0 :(得分:0)

您应该创建一个小的可运行示例来演示您正在做的事情:http://wiki.wxpython.org/MakingSampleApps

与此同时,如果您只是移动自己绘制的对象,那么您可能会发现DragImage演示很有用。它可以在wxPython演示中找到。否则,我建议询问官方的wxPython邮件列表/ Google小组,因为那里有很多经验丰富的wxPython开发人员:https://groups.google.com/forum/?pli=1#!forum/wxpython-users