Попытка сделать перетаскиваемые дочерние элементы прокручиваемого окна в wXPython - PullRequest
0 голосов
/ 27 февраля 2012

Я пытаюсь создать потомков, чьим родителем является 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 голосов
/ 27 февраля 2012

Вам следует создать небольшой исполняемый пример, который демонстрирует, что вы делаете: http://wiki.wxpython.org/MakingSampleApps

Тем временем, если вы просто перемещаетесь вокруг объектов, которые нарисовали сами, то вы можете найти DragImageдемо полезно.Это можно найти в демоверсии wxPython.В противном случае, я бы порекомендовал спросить об этом в официальном списке рассылки wxPython / группе Google, так как там много опытных разработчиков wxPython: https://groups.google.com/forum/?pli=1#!forum/wxpython-users

...