带有滚动条的 Kivy ScrollView 代码错误(或错误?)

Kivy ScrollView code error with scrollbars (or bug?)

我正在玩 Kivy Scrollview,添加滚动条等,然后遇到奇怪的崩溃。我并不特别认为这是一个 bug,它可能是我遗漏的 Scrollviews 上的一些配置元素,但谁知道呢?

鉴于此代码:

"""
Source: 
"""
from kivy.app import App
from kivy.uix.image import Image
from kivy.uix.scrollview import ScrollView
from kivy.core.window import Window

class TutorialApp(App):
    def build(self):

        some_img = Image(source='/home/data/map/Map_07C.jpg', size_hint=(None, None),
                         keep_ratio=True, size=(Window.width * 2, Window.height * 2))
        sv = ScrollView(size=Window.size, bar_width=50,
                        scroll_type=['bars', 'content'], effect_cls='ScrollEffect')
        sv.add_widget(some_img)

        return sv

if __name__ == "__main__":
    TutorialApp().run()

如果我以任何方式单击或触摸滚动条,我都会收到此错误:

   File "kivy_env/lib/python3.8/site-packages/kivy/uix/scrollview.py", line 908, in on_scroll_move
     self.effect_x.update(touch.x)
   File "kivy_env/lib/python3.8/site-packages/kivy/effects/scroll.py", line 116, in update
     self.displacement += abs(val - self.history[-1][1])
 IndexError: list index out of range 

但是 - 如果我首先单击正在滚动的位图,我可以毫无问题地使用滚动条。

怎么了?是否缺少某些 Scrollview 配置? (我花了一段时间才找到 scroll_type 选项来启用条形图,起初我只能用鼠标拖动位图)。或者它是一个错误 - 鉴于它正在引用 history[-1],也许它还不存在?

是的,这是一个错误。刚刚在 Github 上搜索了 Kivy 存储库,发现:

Effects Scroll Exception

link 确实有一个“解决方法”补丁,您可以手动将其应用于已安装的库。刚刚测试了补丁,它解决了我的问题。基本上在 history[-1]

行周围放置一个 try/except/return 块

技术上是一个错误,但我们可以从桌面和移动应用程序中注意到它们在我们使用的桌面应用程序中使用不同的 scroll_type=['bars', 'content'] bars 在我们使用 content 的移动应用程序中,只有当我们使用两种类型的 scroll_type 时才会出现错误,因此我们可以说 scrollview 没有设计使用两种类型的 scroll_type同时

另一种解决方法是调用函数 on_touch_down 检查鼠标的 x 位置并将滚动类型相应地更改为仅 ['Bars'] 或仅 ['Content']。请注意,我将我的设置设置为检查 Window.width - 12,因为这是我使用的滚动条的宽度。默认为 2。

# tutorial.kv
<SV>:
    on_touch_down: self.check_pos()
    bar_width: 12


# main.py
from kivy.uix.scrollview import ScrollView

class SV(ScrollView):
    def check_pos(self):
        if Window.mouse_pos[0] <= (Window.width - 12):
            self.scroll_type = ['content']
        else:
            self.scroll_type = ['bars']