【问题标题】:Kivy drag and drop from ListViewKivy 从 ListView 拖放
【发布时间】:2014-05-25 21:11:08
【问题描述】:

我正在尝试设置一个 ListView 以便

1) 进行选择时,从 ListView 中删除该选择

2) 创建一个 Scatter,其中包含一个带有所选文本的标签

3) 使用相同的点击,Scatter 被拖过屏幕

4) 一旦点击被释放,Scatter 就会被删除。

我在 tkinter 中做了这个,我正在尝试将它转换到 Kivy。在大多数情况下,这非常简单,但我遇到了几个问题。我遇到的第一个问题是选择 ListView。 ListView 的on_touch_down 事件在ListView 适配器的on_selection_change 事件之前被触发,所以如果我绑定到on_touch_down,我会得到之前的选择,而不是当前的选择。第二个问题是拖动 Scatter。目标是让用户在 1 次单击中从 ListView 中进行选择,出现 Scatter 并将其拖过屏幕,然后在释放单击时删除 Scatter。我尝试在绑定到 ListView 的on_touch_down 的以下方法中使用touch.grab()

def onPress(self, view, touch):
    if view.collide_point(touch.x, touch.y):
        self.floatLayout.add_widget(self.scatter)
        touch.grab(self.scatter)

但是当我点击 ListView 时,我得到一个 TypeError: cannot create weak reference to 'weakproxy' object 错误,尽管我的 .kv 文件中有 keyScatter: keyScatter.__self__,并且 keyScatterself.scatter 的 id。

这两个问题有什么好的解决办法吗?

【问题讨论】:

    标签: python kivy


    【解决方案1】:

    对于任何尝试从 ListView 进行拖放操作的人,有一个好消息:存在解决方案。为了解决这个问题,我使用了绑定到ListView的适配器的on_selection_change、ListView的on_touch_down和我用于拖放的Scatter的on_touch_up的方法,如下所示代码块。

    self.listview.bind(on_touch_down=self.press)
    self.scatter.bind(on_touch_up=self.release)
    self.adapter.bind(on_selection_change=self.selectionChange)
    
    def selectionChange(self, adapter):
        if adapter.selection: #Sometimes the selection was [], so a check doesn't hurt 
            names = adapter.data
            self.scatter.children[0].text = adapter.selection[0].text #My scatter has a label as it's first and only child. Here, I'm changing the label's text
            for j in adapter.data:
                if j == adapter.selection[0].text:
                    break
            names.pop(names.index(j))
            self.listview.adapter.data = names
            if(hasattr(self.listview, '_reset_spopulate')): #This is used to reset the ListView
                self.listview._reset_spopulate()
    
    def press(self, view, touch):
        if view.collide_point(touch.x, touch.y) and not touch.is_mouse_scrolling:
            self.scatter.center = touch.pos
            self.floatLayout.add_widget(self.scatter) #The scatter appears on the click
            self.scatter.on_touch_down(touch) #Needs to be called to get the scatter to be dragged
    
    def release(self, scatter, touch):
        if scatter.collide_point(touch.x, touch.y) and touch.grab_current: #Because Kivy's on_touch_up doesn't work like I think it does
    
            #Do whatever you want on the release of the scatter
    
            self.floatLayout.remove_widget(self.scatter) #Remove the scatter on release
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-14
      • 1970-01-01
      • 2011-06-16
      • 2011-09-26
      • 1970-01-01
      • 2012-11-24
      相关资源
      最近更新 更多