I have a Screen that holds a ScrollView that holds a StackLayout of buttons. I can generate as many buttons as I have rows in my database table, but only when the app is first loaded. I have a button that can add rows to my table, but no more buttons are added to the screen unless the app is fully closed and reopened.
<InventoryScreen>:
on_pre_enter: root.updateInv(self)
name: "inventory"
BoxLayout:
orientation: "vertical"
Label:
text: "Inventory"
size_hint: 1, .25
ScrollInventory:
Button:
text: "Back"
size_hint: 1, None
on_release:
app.root.current = "Options"
root.manager.transition.direction = "right"
<ScrollInventory@ScrollView>:
InventoryStack:
size_hint: 1, None
height: self.minimum_height
<InventoryStack>:
orientation: "lr-tb"
padding: ("20dp", "20dp")
spacing: "20dp", "20dp"
class InventoryStack(StackLayout):
def __init__(self, **kwargs):
super().__init__(**kwargs)
for i in Inventory.select():
size = dp(100)
dictItem = model_to_dict(i)
print(dictItem['name'])
invButton = Button(text=dictItem['name'], size_hint=(None, None), size=(size, size))
------------self.add_widget(invButton)
print("-" * 35)
def viewInventory(self):
for i in Inventory.select():
size = dp(100)
dictItem = model_to_dict(i)
print(dictItem['name'])
invButton = Button(text=dictItem['name'], size_hint=(None, None), size=(size, size))
------------self.add_widget(invButton)
print("-" * 35)
class InventoryScreen(Screen):
def updateInv(self, *largs):
InventoryStack().viewInventory()
I've minimized this code as much as possible to identify the problem. It works exactly how I want it to EXCEPT for the self.add_widget(invButton) lines. Just not sure where to look in the kivy docs to find a solution. Thanks in advance.
Your line of code:
InventoryStack().viewInventory()
is creating a new instance of InventoryStack
, and calling viewInventory()
on that new instance. That new instance is not the instance that appears in your GUI, so it has no visible effect. You need a reference to the InventoryStack
that is actually in your GUI.
One way to solve this is to create a class variable that contains a reference to the correct instance. Something like this:
class InventoryStack(StackLayout):
instance = None # class variable to hole reference to the instance
def __init__(self, **kwargs):
super().__init__(**kwargs)
InventoryStack.instance = self
.
.
.
Then use that reference in the updateInv()
method:
class InventoryScreen(Screen):
def updateInv(self, *largs):
InventoryStack.instance.viewInventory()
This is the beginnings of a Singleton
. See this question.