Kivy 小部件不会出现在 Popup/Scrollview/GridLayout 中,而它们确实存在

Kivy widgets don't show up in Popup/Scrollview/GridLayout, while they do exist

在我的应用程序的一部分中,用户可以解锁和更改背景。它曾经在手动制作按钮时起作用。我希望按钮自动生成,这样可以更轻松地向应用程序添加更多背景。

当我尝试使用 for 循环添加按钮时,它给出了以下回溯:

 Traceback (most recent call last):
   File "/Users/jessyliewes/Documents/Python/Whosebug/PopupBgButtonProblem/main.py", line 81, in <module>
     TestApp().run()
   File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/kivy/app.py", line 955, in run
     runTouchApp()
   File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/kivy/base.py", line 570, in runTouchApp
     EventLoop.mainloop()
   File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/kivy/base.py", line 335, in mainloop
     self.idle()
   File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/kivy/base.py", line 379, in idle
     self.dispatch_input()
   File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/kivy/base.py", line 330, in dispatch_input
     post_dispatch_input(*pop(0))
   File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/kivy/base.py", line 299, in post_dispatch_input
     wid.dispatch('on_touch_up', me)
   File "kivy/_event.pyx", line 731, in kivy._event.EventDispatcher.dispatch
   File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/kivy/uix/behaviors/button.py", line 179, in on_touch_up
     self.dispatch('on_release')
   File "kivy/_event.pyx", line 727, in kivy._event.EventDispatcher.dispatch
   File "kivy/_event.pyx", line 1307, in kivy._event.EventObservers.dispatch
   File "kivy/_event.pyx", line 1191, in kivy._event.EventObservers._dispatch
   File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/kivy/lang/builder.py", line 57, in custom_callback
     exec(__kvlang__.co_value, idmap)
   File "/Users/jessyliewes/Documents/Python/Whosebug/PopupBgButtonProblem/layout.kv", line 57, in <module>
     on_release: Factory.PopupBg().open()
   File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/kivy/uix/modalview.py", line 216, in open
     self.center = Window.center
   File "kivy/properties.pyx", line 520, in kivy.properties.Property.__set__
   File "kivy/properties.pyx", line 1459, in kivy.properties.ReferenceListProperty.set
   File "kivy/properties.pyx", line 402, in kivy.properties.Property.get_property_storage
   File "kivy/properties.pyx", line 1422, in kivy.properties.ReferenceListProperty.link_deps
   File "kivy/properties.pyx", line 487, in kivy.properties.Property.fbind
   File "kivy/properties.pyx", line 402, in kivy.properties.Property.get_property_storage
   File "kivy/properties.pyx", line 1636, in kivy.properties.AliasProperty.link_deps
 TypeError: Cannot convert int to kivy.properties.Property

当我尝试在不使用循环的情况下添加按钮(或标签)时,弹出窗口不显示任何小部件。

我这两个实例,它表明按钮(和 GridLayout)确实存在。他们只是不会出现。

这是我的代码:

main.py

# Using kivy 2.0.0 and python3.8

import kivy

from kivy.config import Config  # For setting height (19.5:9)
from kivy.factory import Factory
from kivy.graphics import Rectangle, RoundedRectangle, Color, InstructionGroup
from kivy.uix.button import Button
from kivy.uix.gridlayout import GridLayout

from kivy.app import App
from kivy.lang import Builder

from kivy.uix.boxlayout import BoxLayout
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.popup import Popup

from kivy.properties import ObjectProperty
from kivy.clock import Clock
from kivy.storage.jsonstore import JsonStore
from kivy.uix.scrollview import ScrollView

import packData


kivy.require('2.0.0')  # Version of Kivy
Config.set('graphics', 'width', '360')  # (New Android smartphones e.g. OnePlus 7 series)
Config.set('graphics', 'height', '640')  # (iPhone X, 11 and 12 series, upsampled)
store = JsonStore('resources/user_data.json')  # For saving high score
root_widget = Builder.load_file('layout.kv')

class PopupBg(Popup):
    bg_scrollview = ScrollView(do_scroll_y=False, do_scroll_x=True)
    backgrounds = ['test', 'test', 'test']
    bg_buttons = []

    bg_scrollview = ScrollView(do_scroll_y=False, do_scroll_x=True)
    bg_grid = GridLayout(rows=2, cols=len(backgrounds))
    bg_scrollview.add_widget(bg_grid)
    bg_grid.add_widget(Button(text='CLICK HERE'))
    # for x in range(3):
    #     bg_button = Factory.BackgroundButton()
    #     bg_grid.add_widget(bg_button)
    #
    #     bg_buttons.append(bg_button)

    for c in list(bg_scrollview.children):
        if isinstance(c, GridLayout):
            print('Hello, I am Grid')
            for c in list(bg_grid.children):
                if isinstance(c, Button):
                    print('hello, i am button')
                else:
                    print('No widgets')

class KaruHouse(Screen, BoxLayout):
    pass


class WindowManager(ScreenManager):
    pass


class TestApp(App):
    WindowManager = WindowManager()

    def build(self):
        return self.WindowManager


TestApp().run()

layout.kv

#: kivy 2.1.0
#: import WipeTransition kivy.uix.screenmanager.WipeTransition
#:import hex kivy.utils.get_color_from_hex
#: import JsonStore kivy.storage.jsonstore
#:import Factory kivy.factory.Factory
#: import Clock kivy.clock.Clock

<WindowManager>:
    transition: WipeTransition()
    canvas.before:
        Color:
            rgba: 1, 1, 1, 1
        Rectangle:
            pos: self.pos
            size: self.size
    KaruHouse:
        id: kh

<BackgroundButton@Button>:
    text: '_'
    bold: True
    background_color: 0, 0, 0, 0
    on_press: print(click)
    on_release: self.state='down'
    canvas.before:
        Color:
            rgba: (1,1,1,1)
        RoundedRectangle:
            size: self.width, self.height
            pos: self.pos

<PopupBg>:
    size_hint_y: .65
    size_hint_x: .8

    title: 'Backgrounds'

<KaruHouse>:
    name: "third"
    orientation: 'vertical'
    size: root.width, root.height
    secondary_color: .4,.4,.4,.8
    secondary_color2: 0,.7,.7,.8

    canvas.before:
        Color:
            rgba: 1, 1, 1, 1
        Rectangle:
            pos: self.pos
            size: self.size


    Button:
        text: 'Backgrounds'
        size: root.width/2, root.height/12
        size_hint: None, None
        on_release: Factory.PopupBg().open()
        pos: root.width/4, root.height/1.5
        background_color: 0, 0, 0, 0
        canvas.before:
            Color:
                rgba: root.secondary_color if self.state=='normal' else root.secondary_color2
            RoundedRectangle:
                size: self.size
                pos: self.pos

    Button:
        text: "Menu"
        font_size: 32
        on_release: print('click')
        size: root.width/2, root.height/12
        size_hint: None, None
        pos: root.width/4, root.height/3.3
        background_color: 0, 0, 0, 0
        canvas.before:
            Color:
                rgba: root.secondary_color if self.state=='normal' else root.secondary_color2
            RoundedRectangle:
                size: self.size
                pos: self.pos

ScrollView 和 GridLayout 曾经在 layout.kv 中,但由于它不起作用,我尝试将它们添加到 .py 文件中。

问题是您没有用小部件初始化 class PopupBg。在 python 中,您可以使用 __init__ 构造函数来做到这一点。

class PopupBg(Popup):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)

        bg_scrollview = ScrollView(do_scroll_y=False, do_scroll_x=True)
        backgrounds = ['test', 'test', 'test']
        bg_buttons = []

#       bg_scrollview = ScrollView(do_scroll_y=False, do_scroll_x=True) # Repeated.
        bg_grid = GridLayout(rows=2, cols=len(backgrounds))
        bg_scrollview.add_widget(bg_grid)
        bg_grid.add_widget(Button(text='CLICK HERE'))
        for x in range(3):
             bg_button = Factory.BackgroundButton()
             bg_grid.add_widget(bg_button)
        
             bg_buttons.append(bg_button)

        for c in list(bg_scrollview.children):
            if isinstance(c, GridLayout):
                print('Hello, I am Grid')
                for c in list(bg_grid.children):
                    if isinstance(c, Button):
                        print('hello, i am button')
                    else:
                        print('No widgets')
        # Now add everything in this popup.
        self.add_widget(bg_scrollview)