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

Time:03-21

In a part of my app, users are able to unlock and change backgrounds. It used to work when the buttons were made manually. I wanted the buttons made automatically so it would be easier to add more backgrounds to the app.

When I try to add buttons using a for loop, it gives the following traceback:

 Traceback (most recent call last):
   File "/Users/jessyliewes/Documents/Python/StackOverflow/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/StackOverflow/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

When I tried to add a button (or a label) without using a loop, the Popup shows no widgets.

I both instances, it shows that the buttons (and the GridLayout) do exist. They just won't appear.

Here is my code:

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

The ScrollView and GridLayout used to be in layout.kv, but since it didn't work I tried to add them in the .py file.

CodePudding user response:

The problem is that you have nowhere initialized class PopupBg with the widgets. In python you can do that with the __init__ constructor.

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)
  • Related