how to use nested for loop with on_parent in kivy - python

i want to make nested for loop in kivy language by using on_perent then i try the slashes but there is error invalid indentation must be a multiple of 4 spaces i don't know what to do and there is no other than slashes
from kivy.app import App
from kivy.lang import Builder
kv = Builder.load_string('''
#:import Button kivy.uix.button.Button
BoxLayout:
BoxLayout:
on_parent:for i in range(2):\n \t \b\b\b\b\b \
on_parent:for i in range(3):\n \t \
on_parent:self.add_widget(Button(text=str(i)))
''')
class TestApp(App):
def build(self):
return kv
TestApp().run()

This is a way of doing the nested for loop but I don't understand what you are trying to achieve
from kivy.app import App
from kivy.lang import Builder
kv = Builder.load_string('''
#:import Button kivy.uix.button.Button
BoxLayout:
BoxLayout:
on_parent:
if not self.children: [self.add_widget(Button(text=str(j))) for i in range(2) for j in range(3)]
''')
class TestApp(App):
def build(self):
return kv
TestApp().run()

Related

How to combine kivy file and loops in python files?

I'm learning how to use kivy. And to get things a little more difficult, I'm using kivyMD to use themes.
I'm trying to simply create a layout in a kivy file and fill it with a python loop in the python file.
My python file, for example :
from kivy.lang import Builder
from kivymd.app import MDApp
from kivymd.uix.label import MDLabel
from kivymd.uix.screen import MDScreen
KV="""
MyWidget:
MDBoxLayout:
orientation: 'vertical'
MDLabel:
text:"hello world !"
halign: 'center'
MDGridLayout:
id: _grid
col: 2
MDLabel:
text:"hello world !"
halign: 'center'
"""
class MyWidget(MDScreen):
def on_grid(self):
for i in range(6):
self.ids._grid.add_widget(MDLabel(text=str(i+1)))
pass
#Déclaration du moteur d'application
class MainApp(MDApp):
def build(self):
return Builder.load_string(KV)
if __name__=='__main__':
MainApp().run()
But the GridLayout stays empty.
I really search and tried other solutions with ObjectProperty() but I got even more errors. And I was unable to find a simple example, something less specific and more academic.
What is the best way to create an empty nested widget in a kv file and then fill it with a python loop at launch ?
Thank you for your help.
After a lot of researchs, I found a solution. I hope it will help someone.
'''
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.properties import ObjectProperty
from kivy.lang import Builder
KV="""
<MainScreen>:
grid: _grid
BoxLayout:
Label:
text: "Hello 1 !"
GridLayout:
id: _grid
cols:2
Label:
text: "Hello 2 !"
"""
Builder.load_string(KV)
class MainScreen(Screen):
grid = ObjectProperty()
def __init__(self, **kwargs):
super(MainScreen, self).__init__(**kwargs)
for i in range(6):
self.grid.add_widget(Label(text=str(i)))
class MyApp(App):
def build(self):
return MainScreen()
if __name__ == '__main__':
MyApp().run()

Can someone provide a working code of loading data of text file to Label of kivy

I am able to get the data in main app class and run it to get as Label but when I want to do the same by getting data in main app class where as defining Label in another class, it's giving name error.
import kivy
from kivy.app import App # import Kivy App module to create
from kivy.uix.label import Label # import Label Module
kivy.require('1.11.1')
class MyKivyApp(App):
def build(self):
f=open('tesit.txt','r')
t=f.read()
return Label(text =t)
rt=MyKivyApp()
rt.run()
Your lines:
rt=MyKivyApp()
rt.run()
are inside the MyKivyApp. Just unindent those two lines to get them outside of the App class.
This's how we can read a text file and display it as label in another screen in kivy.
from kivy.app import App
from kivy.uix.screenmanager import Screen
from kivy.lang import Builder
from kivy.properties import StringProperty
class Screen1(Screen):
f=open('test.txt','r')
t=f.readlines()
b=t[0]
f.close()
class Screen2(Screen):
username = StringProperty("")
root = Builder.load_string('''
<Screen1>:
name:'xy'
id:loginscreen
BoxLayout:
orientation: "vertical"
Button:
text:'Execution button'
on_release: root.manager.current = "screen2"
<Screen2>:
name: "screen2"
FloatLayout:
Label:
text: root.username
Button:
text:'Back to menu'
size_hint:.3,.3
on_release: root.manager.current = "xy"
ScreenManager:
Screen1:
id:loginscreen
Screen2:
username: loginscreen.b
''')
class MyApp(App):
def build(self):
return root
r=MyApp()
r.run()

Kivy Spinner adds a widget that is not codded

Can someone explain why below code adds this Close Button on the bottom of the window you can see on the pic? How to get rid of this?
CODE
from kivy.app import App
from kivy.lang import Builder
kv = '''
<MenuSpinner#Spinner>
<Menu#BoxLayout>
orientation: 'vertical'
MenuSpinner:
text: 'SPINNER'
values: ['1', '2']
BoxLayout:
Menu:
'''
sm = Builder.load_string(kv)
class TestApp(App):
def build(self):
return sm
if __name__ == '__main__':
TestApp().run()
The button is coming from the MenuSpinner, which is already present in Kivy (mostly internal, used by kivy.uix.settings). That class should probably be named differently on the Kivy side, but in any case renaming your version should fix the problem.

Kivy: How to refernce kv ID in Python?

I'm new to Kivy and I would have to think this is possible, but I can't figure it out - How can I update a Kivy label when a button is pressed, but only by referencing that Kivy id within Python? (The reason I'm trying to do it this way is because in my actual application, I would like several labels to update at once, which I was hoping I could do all within the button_pressed equivalent button I have in my app).
In the simple example below, I'm just trying to have the button pressed and then have the label update to 'Updated!'
Thanks very much!
My Python code:
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.widget import Widget
from kivy.properties import StringProperty
import random
class TestingWidget(BoxLayout):
# This is the kv id of the Label I would like to update
label_to_update = StringProperty('')
# This is the action I would like to happen when the button is pressed
def button_pressed(self):
label_to_update.text = 'Updated!'
class TestButtonApp(App):
def build(self):
return TestingWidget()
if __name__ == '__main__':
TestButtonApp().run()
My kv file:
<TestingWidget>:
BoxLayout:
orientation: 'horizontal'
Button:
text: 'test'
on_press: root.button_pressed()
Label:
id: label_to_update
text: 'Trying to get this to update'
You definitely update all label when you press the button. Just crate a StringProperty for each and do what you are doing now.
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.widget import Widget
from kivy.properties import StringProperty
from kivy.lang import Builder #used because I didn't want to create two files
import random
Builder.load_string('''
<TestingWidget>:
BoxLayout:
orientation: 'horizontal'
Button:
text: 'test'
on_press: root.button_pressed()
Label:
id: label_to_update
text: root.label_to_update
''')
class TestingWidget(BoxLayout):
# This is the kv id of the Label I would like to update
label_to_update = StringProperty('Trying to get this to update')
#default text set
# This is the action I would like to happen when the button is pressed
def button_pressed(self):
self.label_to_update = 'Updated!'
class TestButtonApp(App):
def build(self):
return TestingWidget()
if __name__ == '__main__':
TestButtonApp().run()

Return ID of button when clicked Kivy Python

Simple problem I'm having:
When I click a button in my Kivy/Python app, I want to gain access to the ID of that button.
# Kivy code
Button:
id: position_1
on_press: app.access_button_id()
I have had various trial and error attempts but I cannot figure it out. The button is nested as follows (as part of a bigger app), if this is a factor in my problem:
FloatLayout:
AnchorLayout:
ScreenManager:
Screen:
BoxLayout:
FloatLayout:
Button:
id: position_1
on_press: app.access_button_id()
Here is my Python code, which returns all of the id's. That's as close as I have got:
# Python code
def access_button_id(name):
print(self.root.ids)
The problem I've got is that I don't even know what I should be looking at in the documentation as I do not fully understand the terminology yet, so I can't find the right information to learn from.
EDIT:
The (name) passed into the function is for some other functionality, not related to this problem.
You already know the id - you set it yourself. These are mostly used as a hard-coded values in your code:
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.lang import Builder
Builder.load_string('''
<MyWidget>:
Button:
id: id_value_1
text: 'Print my id'
on_press: print({'id_value_1': self.proxy_ref})
Button:
id: id_value_2
text: 'Print all ids'
on_press: print(root.ids)
''')
class MyWidget(BoxLayout):
pass
class MyApp(App):
def build(self):
widget = MyWidget()
print({'id_value_1': widget.ids['id_value_1']})
return widget
if __name__ == '__main__':
MyApp().run()
Why do you need id of a Button if you already have an access to it? What are you trying to accomplish?
EDIT
An example solution to problem mentioned in the comment:
import random
import functools
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.popup import Popup
from kivy.uix.button import Button
from kivy.lang import Builder
Builder.load_string('''
<MyWidget>:
Button:
text: 'B1'
on_press: root.open_popup(self)
Button:
text: 'B2'
on_press: root.open_popup(self)
''')
class MyWidget(BoxLayout):
def open_popup(self, caller):
fun = functools.partial(self.rename, caller)
popup = Popup(
title='Test popup',
content=Button(
text='rename',
on_press=fun
),
size_hint=(None, None), size=(400, 400)
)
popup.open()
def rename(self, caller, *args):
caller.text = ''.join(chr(random.randint(48, 90)) for i in range(5))
class MyApp(App):
def build(self):
return MyWidget()
if __name__ == '__main__':
MyApp().run()

Categories

Resources