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

Posted

技术标签:

【中文标题】带有滚动条的 Kivy ScrollView 代码错误(或错误?)【英文标题】:Kivy ScrollView code error with scrollbars (or bug?) 【发布时间】:2021-10-31 06:26:23 【问题描述】:

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

鉴于此代码:

"""
Source: https://***.com/questions/35626320/kivy-image-scrolling
"""
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],也许它还不存在?

【问题讨论】:

从技术上讲,有一个解决方法——我会告诉客户,“每次运行这个应用程序时,一定要点击中心,敢于使用滚动条之前”。 :) 【参考方案1】:

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

Effects Scroll Exception

该链接确实有一个“解决方法”补丁,您可以手动将其应用于已安装的库。刚刚测试了补丁,它解决了我的问题。基本上在 history[-1] 的行周围放置一个 try/except/return 块

【讨论】:

【参考方案2】:

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

【讨论】:

也许可以,但scroll_type 变量旨在采用列表参数,而不是单个参数。它确实适用于两种类型的滚动(对我来说,在 PC 上)——如果我要么先进行鼠标滚动(从而填充历史变量),要么应用补丁。【参考方案3】:

另一种解决方法是调用 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']

【讨论】:

以上是关于带有滚动条的 Kivy ScrollView 代码错误(或错误?)的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Kivy ScrollView 中滚动 GridLayout?

Kivy - 创建一个可扩展的 ScrollView

标签的 Kivy ScrollView 不会滚动

Kivy ScrollView - 不滚动

为啥孩子的 Kivy ScrollView 孩子不可滚动?

Kivy Scrollview 自动滚动到新文本。防止向上滚动