【问题标题】:Kivy scatter region is limited to window sizeKivy 分散区域受限于窗口大小
【发布时间】:2016-09-20 05:34:31
【问题描述】:

我基本上遇到了问题,唯一的“可抓取”分散区域完全由我正在查看程序的窗口大小定义,而不是分散的大小。

这是一个错误的工作示例:

from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.button import Button
from kivy.uix.gridlayout import GridLayout
from kivy.uix.scatter import Scatter

class AppFrame(GridLayout):
    def __init__(self,**kwargs):
        super(AppFrame,self).__init__(**kwargs)
        self.myscatter=Scatter(
            width=2000,
            height=200,
            do_rotation=False,
            do_scale=True,
            do_translation=True)
        self.add_widget(self.myscatter)
        self.layout=GridLayout(cols=30,width=2000,height=200)
        self.myscatter.add_widget(self.layout)

        for i in range(300):
            self.layout.add_widget(Button(text=str(i)))

class TestApp(App):
    def build(self):
        return AppFrame(cols=3)

if __name__ == '__main__':
    TestApp().run()

在我的屏幕上,如果我使用散点图向右移动(使用按钮增加),我无法抓取按钮 ~10-11 之后的任何东西。如果我调整我的屏幕大小,我可以抓得更远一点。如果我把屏幕变小,可抓取区域会缩小,甚至可能无法触及。我到底该如何解决这个问题?

我正在使用带有 Android 模拟器的 Kivy 环境,所以我有一个相当大的屏幕。不幸的是,如果我把它移到手机上,屏幕尺寸会显着缩小,从而使这个错误有效地禁用滚动。

(顶层布局用于添加菜单。实际菜单不包含在此示例中,因为不需要重新创建错误)

我想弄清楚的主要事情是:

  1. 这是代码问题还是安卓模拟器问题?
  2. 如果是代码问题,能否解决?如何解决?
  3. 如果无法修复,我还能如何获得此功能?

更新: 在 George Bou 发表评论后,我将问题隔离在 scatter 的 BBOX 内。创建时,散布 bbox 大小为 2000x200。但是,创建窗口后它是 800x600(弹出的屏幕的默认大小)。

令人讨厌的是,我不知道如何解决这个问题。如果我在任何点(即在按钮中)更改散点的宽度/高度,只要发生平移/缩放,它就会立即重置回 800x600。任何人都知道如何让 scatter 停止自动调整其 bbox 到窗口的大小?

【问题讨论】:

  • 我找不到你的问题的答案,但我看到了别的东西。只有在可视屏幕内的按钮才可点击,而外部的按钮不可点击。要解决这个问题,请在 Scatter 参数中添加do_collide_after_children=True,所有按钮都将变为可点击。我还看到,Scatter 区域位于 Button 区域上方。我不知道这是有意为之还是您希望这些区域匹配。
  • 这实际上很有帮助。这将问题缩小到散点图的边界框。我发现在创建窗口后,散点图的边界框被调整为窗口的大小。即,如果我在 init 期间打印边界框,它会显示为应有的大小,但如果我在按下按钮时打印它,它会小得多。

标签: python kivy


【解决方案1】:

好的。我想不出用香草散射对象本身来做这件事的方法,但我做了一个似乎工作得很好的解决方法。

基本上,scatter 控制通过其类中的collide_point 方法可抓取的内容。这个类引用了它自己的宽度/高度(它们是不可变的)。因此,我创建了一个自定义的 scatter 类,用可更改的东西覆盖了 collide_point 方法。

class CustScatter(Scatter):
    def collide_point(self, x, y):
        x, y = self.to_local(x, y)
        return 0 <= x <= self.xboundval and 0 <= y <= self.yboundval
    def custSetBounds(self,xval,yval):
        self.xboundval=xval
        self.yboundval=yval

要使用它,我只需确保在创建类的实例后立即设置边界 (custSetBounds)。

Kivy 真的让我想念 Tkinter...

【讨论】:

    【解决方案2】:

    我自己也遇到了。添加 size_hint=(None,None) 以阻止它使用 windows 尺寸。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-31
      • 2013-03-29
      • 2018-07-05
      • 2012-12-10
      • 2013-03-24
      • 1970-01-01
      相关资源
      最近更新 更多