Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/353.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在kivy中嵌套小部件_Python_User Interface_Widget_Kivy - Fatal编程技术网

Python 在kivy中嵌套小部件

Python 在kivy中嵌套小部件,python,user-interface,widget,kivy,Python,User Interface,Widget,Kivy,我正在尝试用kivy制作一个界面,我想关于自定义小部件以及如何对它们进行层次化,我还不了解一些基本的东西,即使在阅读了教程之后。我认为我更倾向于框模型html,因此在本机GUI中嵌套小部件的方式对我来说仍然有些陌生 一些背景: 我就如何添加背景进行了咨询(它回答了一个问题:“如何将背景图像/颜色/视频/…添加到布局”,我相信我是在用_update _rect方法进行复制) 有一个触地事件 K、 我正试图让我的应用程序看起来像这样 据我所知,以下是我需要的东西: 你有一个应用程序 该应用程序有一

我正在尝试用kivy制作一个界面,我想关于自定义小部件以及如何对它们进行层次化,我还不了解一些基本的东西,即使在阅读了教程之后。我认为我更倾向于框模型html,因此在本机GUI中嵌套小部件的方式对我来说仍然有些陌生

一些背景:

  • 我就如何添加背景进行了咨询(它回答了一个问题:“如何将背景图像/颜色/视频/…添加到布局”,我相信我是在用_update _rect方法进行复制)

  • 有一个触地事件

  • K、 我正试图让我的应用程序看起来像这样

    据我所知,以下是我需要的东西:

  • 你有一个应用程序
  • 该应用程序有一个根
  • 根有背景,比如说背景是白色的
  • 背景包含一个支架,也就是说支架与背景有一点距离,并且是灰色的。我确实希望它是一个小部件,而不仅仅是一个非小部件画布,因为我希望持有者也能对点击事件做出反应。单击时,它会变成随机颜色。(只是为了表明它在做些什么。)
  • 持有者包含两个自定义小部件。这些是带标签的圆圈,每个都是绿色的。单击时,它们会随机改变颜色(只是为了显示它们正在做某事)
  • 这是我的代码,它不再崩溃,但不会显示任何颜色或任何类型的对象

    #!/usr/bin/kivy
    import kivy
    kivy.require('1.7.2')
    
    from random import random
    from kivy.app import App
    from kivy.uix.widget import Widget
    from kivy.uix.floatlayout import FloatLayout
    from kivy.graphics import Color, Ellipse, Rectangle
    
    class MyApp(App):
        title = 'My App'
        def build(self):
            root = RootWidget()
            root.bind(
                size=self._update_rect,
                pos=self._update_rect)
        def _update_rect(self, instance, value):
            self.rect.pos = instance.pos
            self.rect.size = instance.size
    
    class RootWidget(FloatLayout):
        def __init__(self, **kwargs):
            super(RootWidget, self).__init__(**kwargs)
            with self.canvas.before:
                Color(1, 0, 0, 1) # This RED does not display.
                self.rect = Rectangle(
                                        size=self.size,
                                        pos=self.pos,
                                        text="some junk!")  # This label does not display.
            mybackground = Background()
            self.add_widget(mybackground)
        def _update_rect(self, instance, value):
            self.rect.pos = instance.pos
            self.rect.size = instance.size
    
    class Background(Widget):
        def __init__(self, **kwargs):
            super(Background, self).__init__(**kwargs)
            with self.canvas.before:    
                Color(1, 1, 1, 1)       # This WHITE does not display
                self.rect = Rectangle(
                                        size=self.size,
                                        pos=self.pos,
                                        text="More stuff!")  # This label does not display.
            myholder = Holder()
            self.add_widget(myholder)
        def _update_rect(self, instance, value):
            self.rect.pos = instance.pos
            self.rect.size = instance.size
    
    class Holder(Widget):
        def __init__(self, **kwargs):
            super(Holder, self).__init__(**kwargs)
            with self.canvas.before:    
                Color(0.25, 0.25, 0.25, 1) # This GRAY does not display
                self.rect = Rectangle(
                                        size=self.size,
                                        pos=self.pos,
                                        text="More stuff!")  # This does not display.
            c1 = Circley(label="Label 1")  # I see I'd need to do some size/pos math here to center
            c2 = Circley(label="Label 2")  # but since everything isn't working, I've tabled this.
            self.add_widget(c1)
            self.add_widget(c2)
        def _update_rect(self, instance, value):
            self.rect.pos = instance.pos
            self.rect.size = instance.size
        def on_touch_down(self, touch):
            rcolor = Color(random(), random(), random(), 1)
            with self.canvas:
                self.color = rcolor
    
    class Circley(Widget):
        def __init__(self, label='label', **kwargs):
            super(Circley, self).__init__(**kwargs)
            with self.canvas.before:    
                Color(0, 1, 0, 1) # This GREEN does not display
                self.circ = Ellipse(
                            size=self.size,
                            pos=self.pos,
                            text=label
                )
        def _update_circ(self, instance, value):
            self.circ.pos = instance.pos
            self.circ.size = instance.size
        def on_touch_down(self, touch):
            rcolor = Color(random(), random(), random(), 1)
            with self.canvas:
                self.color = rcolor
    
    if __name__ == '__main__':
        MyApp().run()
    

    有没有关于我做错了什么以及如何正确嵌套这些小部件的指针?

    出现空白屏幕的原因是应用程序的
    build()
    方法没有返回任何内容。无论它返回什么,都将是根小部件,但即使您制作了一些小部件,您也不会返回一个,因此不会显示任何内容

    如果您解决了这个问题,您可以再次运行应用程序,但您会立即得到一个错误,例如
    MyApp没有属性rect
    。这是因为您的根小部件会立即调整大小和位置以填充窗口,这(根据您的
    root.bind
    行)会触发
    MyApp.\u update\u rect
    。但是,此方法尝试修改MyApp.rect.pos…但是应用程序没有self.rect!您可能打算绑定到
    root.\u update\u rect
    ,而不是应用程序的方法。(编辑:我绑定到
    根目录。_update_rect
    ,现在至少出现了红色背景和绿色圆圈。)

    编辑:顺便说一句,使用kv语言会容易得多,它可以自动处理许多小部件的创建、矩形绑定等

    我现在没有时间修复它,但是这两个问题可能会帮助您修复整个流程。如果其他人都没有,我会尝试稍后发布一个更完整的答案


    根据评论,这里有一个更新的MyApp

    class MyApp(App):
        title = 'My App'
        def build(self):
            root = RootWidget()
            root.bind(
                size=root._update_rect,
                pos=root._update_rect)
    

    这很有帮助,但我不明白你所说的
    是什么意思。然而,这个方法试图修改MyApp.rect.pos…但是这个应用没有self.rect!您可能打算绑定到root.\u update\u rect,而不是应用程序的方法。(编辑:我绑定到根目录下。_update_rect,现在至少出现了红色背景和绿色圆圈。)
    这对MyApp(App)的``def_update_rect(self,instance,value)意味着什么变化:self.rect.pos=instance.pos self.rect.size=instance.size``?我应该将self.rect.pos更改为root,并将root作为输入传递给该函数?我已经在更新的MyApp类中编辑了我想要的更改。它根本没有一个_update_rect方法,因为应用程序没有矩形。
    from kivy.app import App
    from kivy.uix.floatlayout import FloatLayout
    from kivy.uix.widget import Widget
    from kivy.graphics import Color, Rectangle, Ellipse
    
    
    class MyApp(App):
        title = 'My App'
        def build(self):
            root = RootWidget()
            root.bind(
                size=root._update_rect,
                pos=root._update_rect)
            return root
    
    class RootWidget(FloatLayout):
        def __init__(self, **kwargs):
            super(RootWidget, self).__init__(**kwargs)
            with self.canvas.before:
                Color(1, 0, 0, 1) # This RED does not display.
                self.rect = Rectangle(
                                        size=self.size,
                                        pos=self.pos,
                                        text="some junk!")  # This label does not display.
            mybackground = Background()
            self.add_widget(mybackground)
        def _update_rect(self, instance, value):
            self.rect.pos = instance.pos
            self.rect.size = instance.size
    
    class Background(Widget):
        def __init__(self, **kwargs):
            super(Background, self).__init__(**kwargs)
            with self.canvas.before:    
                Color(1, 1, 1, 1)       # This WHITE does not display
                self.rect = Rectangle(
                                        size=self.size,
                                        pos=self.pos,
                                        text="More stuff!")  # This label does not display.
            myholder = Holder()
            self.add_widget(myholder)
        def _update_rect(self, instance, value):
            self.rect.pos = instance.pos
            self.rect.size = instance.size
    
    class Holder(Widget):
        def __init__(self, **kwargs):
            super(Holder, self).__init__(**kwargs)
            with self.canvas.before:    
                Color(0.25, 0.25, 0.25, 1) # This GRAY does not display
                self.rect = Rectangle(
                                        size=self.size,
                                        pos=self.pos,
                                        text="More stuff!")  # This does not display.
            c1 = Circley(label="Label 1")  # I see I'd need to do some size/pos math here to center
            c2 = Circley(label="Label 2")  # but since everything isn't working, I've tabled this.
            self.add_widget(c1)
            self.add_widget(c2)
        def _update_rect(self, instance, value):
            self.rect.pos = instance.pos
            self.rect.size = instance.size
        def on_touch_down(self, touch):
            rcolor = Color(random(), random(), random(), 1)
            with self.canvas:
                self.color = rcolor
    
    class Circley(Widget):
        def __init__(self, label='label', **kwargs):
            super(Circley, self).__init__(**kwargs)
            with self.canvas.before:    
                Color(0, 1, 0, 1) # This GREEN does not display
                self.circ = Ellipse(
                            size=self.size,
                            pos=self.pos,
                            text=label
                )
        def _update_circ(self, instance, value):
            self.circ.pos = instance.pos
            self.circ.size = instance.size
        def on_touch_down(self, touch):
            rcolor = Color(random(), random(), random(), 1)
            with self.canvas:
                self.color = rcolor
    
    if __name__ == '__main__':
        MyApp().run()