【问题标题】:Kivy Scatter z-indexKivy Scatter z-index
【发布时间】:2018-11-26 15:00:22
【问题描述】:

我正在尝试制作一个用于模拟简单生态系统的 kivy 应用程序,带有一种交互式地图,可以通过用户拖动来缩放和定位。我实现此目的的第一种方法是使用 Kivy Scatter 小部件,它似乎满足了这些要求。这是我的代码(为简单起见,只是带有按钮的 gui 和右侧的地图,带有大红色矩形):

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import ObjectProperty
from kivy.graphics import Rectangle, Color

class GUI(BoxLayout):

    board = ObjectProperty(None)

    def draw(self):
        with self.board.canvas:
            Color(1,0,0)
            Rectangle(pos=(0,0),size=(300,300))

class TestApp(App):

    def build(self):
        gui = GUI()
        gui.draw()
        return gui

if __name__=="__main__":
    app = TestApp()
    app.run()

还有我的 .kv 文件:

#:kivy 1.0.9


<GUI>:
    board: scatter_board
    orientation: 'horizontal'
    spacing: 30
    padding: 30
    BoxLayout:
        size_hint: 0.25, 1
        orientation: 'vertical'
        Button:
            text: 'Start/Resume'
        Button:
            text: 'Stop'
    Scatter:
        id: scatter_board
        size_hint: 0.75,1

但是,在这种情况下,当用户将地图拖到按钮上时,无法再单击它(单击时不会突出显示)。我试过了:

  • 将 scatter 的“auto_bring_to_front”设置为 False
  • 使用 scatter 和按钮的父 BoxLayout 的 'index' 属性来操作 z-index。

所以基本上我希望“地图”不要遮蔽按钮,而是保持在按钮下方。是否可以使用 Scatter 实现这种效果?还是分散的错误用例,我应该改变方法?如果是这样,你知道任何类似且可能简单的方法吗?

【问题讨论】:

标签: python user-interface kivy


【解决方案1】:

我也在为同样的问题而苦苦挣扎。 阅读上面的答案后,我发现您需要将 Scatter 放在自己的 boxlayout 中。并且不要使用 ScatterLayout,就像我最初做的那样,因为那样它就不会做你想要的(在按钮下面而不是在它们上面)。

我是这样做的:

# Creating Scatter Class 
class TreeWidget(Scatter):
    def __init__(self, **kwargs):
        super(TreeWidget, self).__init__(**kwargs)
        #self.auto_bring_to_front = False
        ...

class ShowApp(App): 
    def build(self):
        treeBox = BoxLayout()
        self.treeWidget = TreeWidget()
        treeBox.add_widget(self.treeWidget)

        buttonFile = Button(text='File', size_hint=(None, None), size=(60, 30))
        buttonFile.bind(on_press=self.chooseFile)
        buttonSave = Button(text='Save', size_hint=(None, None), size=(60, 30))
        buttonSave.bind(on_press=self.saveFile)
        buttonBox = BoxLayout(orientation='horizontal')
        buttonBox.add_widget(buttonFile)
        buttonBox.add_widget(buttonSave)
    
        boxLayout = BoxLayout(orientation='vertical')
        boxLayout.add_widget(treeBox)
        boxLayout.add_widget(buttonBox)
        return boxLayout

【讨论】:

    【解决方案2】:

    为了达到你想要的效果,你需要在你的kv文件中使用FloatLayout..

    <GUI>:
        BoxLayout:
            Scatter:
                Board:
                    canvas:
                        Rectangle:
                            size: (100,300)
        BoxLayout:
            orientation :"vertical"
            Button:
                text: "gi"
            Button:
                text: "gi"
    

    将此添加到主文件

    class GUI(BoxLayout):
        board = ObjectProperty(None)
    
        # def draw(self):
        #     with self.board.canvas:
        #         Color(1,0,0)
        #         Rectangle(pos=(0,0),size=(300,300))
    
    class Board(Widget):
        pass
    
    class TestApp(App):
        def build(self):
            gui = GUI()
            # gui.draw()
            return gui
    
    if __name__=="__main__":
        app = TestApp()
        app.run()
    

    别忘了导入 FloatLayout,,

    【讨论】:

    • 对不起,我不太明白 FloatLayout 是从哪里来的,因为它不在代码中的任何地方,你能解释一下吗?
    • 我把它去掉了,所以我猜这里没有nee,我最初用它来定位小部件
    • 所以“为了实现这一点,我需要使用 FLoatLayout”,但是之后我可以删除它???
    • 你可以这样做忽略 FloatLayout
    • 那么实现这一点的实际方法是什么?使用单独的布局,将它们按不同的顺序排列,删除绘图方法???您的回答没有解释它,我只是对它更加困惑(而且您这样做的方式不符合我的需要,因为我需要从 .py 文件内部在画布上绘制)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-27
    • 2011-07-13
    • 2012-11-05
    • 2021-06-17
    • 2011-12-06
    • 1970-01-01
    相关资源
    最近更新 更多