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)