main:
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.uix.widget import Widget
class testclass:
def someth(txt):
print (txt)
#how get access to textinput from begin Screen here?
class BeginScreen(Screen):
def __init__(self,**kwargs):
super().__init__()
self.layout =BoxLayout(orientation='vertical',padding=20,spacing=5,)
self.btn=Label(text=str('Hello'))
self.layout.add_widget(self.btn)
self.btn=TextInput(id='test',text='')
self.layout.add_widget(self.btn)
self.btn=Button(text='Button!', on_press=testclass.someth('?'))
# what write in ? to send textinput text to testclass.someth?
self.layout.add_widget(self.btn)
self.add_widget(self.layout)
print(self.layout.ids) #why i have no ids? textinput have id
class TestApp(App):
from kivy.config import Config
Config.set('graphics', 'width', '800')
Config.set('graphics', 'height', '400')
def build(self):
sm = ScreenManager()
sm.add_widget(BeginScreen(name='test'))
return sm
TestApp().run()
So how can i access the textinput? I have id='test' but when i printing layouts id is saying i have noone. Why? Someone can explain me what im doing wrong and how can i make it good?
from functools import partial
To access the textinput in your external method, you could use partial functions or lambda function.
self.ids
You are getting None or empty dictionary because you don't have a kv file.
Note
When your kv file is parsed, kivy collects all the widgets tagged with id’s and places them in this self.ids dictionary type property.
Please refer to my example below for deatils.
Example
main.py
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from functools import partial
class testclass:
def someth(*args, txt):
print(txt)
class BeginScreen(Screen):
def __init__(self, **kwargs):
super(BeginScreen, self).__init__(**kwargs)
layout = BoxLayout(orientation='vertical', padding=20, spacing=5)
layout.add_widget(Label(text=str('Hello')))
# layout.add_widget(TextInput(id='test', text='')) # id in python+kivy is deprecated
txtInput = TextInput(text='text input')
layout.add_widget(txtInput)
self.ids['test'] = txtInput
layout.add_widget(Button(text='Button!', on_press=partial(testclass.someth, txt=self.ids.test.text)))
self.add_widget(layout)
print("self.ids={}".format(self.ids))
print("self.ids['test']={}".format(self.ids['test']))
print("self.ids['test'].text={}".format(self.ids['test'].text))
print("self.ids.test.text={}".format(self.ids.test.text))
for key, val in self.ids.items():
print("key={0}, val={1}".format(key, val))
class TestApp(App):
from kivy.config import Config
Config.set('graphics', 'width', '800')
Config.set('graphics', 'height', '400')
def build(self):
sm = ScreenManager()
sm.add_widget(BeginScreen(name='test'))
return sm
TestApp().run()
Output
Related
In this example I'm adding a ListProperty with a default value. If I write a new value in kv
, it's keeping the default value instead of taking the new one. (here text_list: ["Apple","Orange","Banana"] should replace text_list = ListProperty(["WHY DEFAULT PARAMETER IS STILL HERE :("]) but it's not the case.
Is there a way to write value on new property from .kv file ?
from kivy.lang import Builder
from kivymd.app import MDApp
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import ListProperty
KV = '''
BoxLayout:
ChoiceList:
text_list: ["Apple","Orange","Banana"]
'''
class ChoiceList(BoxLayout):
text_list = ListProperty(["WHY DEFAULT PARAMETER IS STILL HERE :("])
def __init__(self, **kwargs):
super().__init__(**kwargs)
for text in self.text_list:
print(text)
class App(MDApp):
def build(self):
self.box = Builder.load_string(KV)
return self.box
App().run()
Thanks to Kivy Discord:
from kivy.lang import Builder
from kivymd.app import MDApp
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import ListProperty
KV = '''
BoxLayout:
ChoiceList:
text_list: ["Apple","Orange","Banana"]
'''
class ChoiceList(BoxLayout):
text_list = ListProperty(["WHY DEFAULT PARAMETER IS STILL HERE :("])
def on_kv_post(self, base_widget):
super().on_kv_post(base_widget)
for text in self.text_list:
print(text)
class App(MDApp):
def build(self):
self.box = Builder.load_string(KV)
return self.box
App().run()
from kivy.uix.button import Button
from kivy.uix.behaviors.button import ButtonBehavior
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.image import Image
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.clock import Clock
from kivy.uix.widget import Widget
from kivy.graphics import BorderImage
from kivy.graphics import Color, RoundedRectangle, Rectangle, Triangle
from kivy.core.window import Window
#from kivy.config import Config
from kivy.uix.checkbox import CheckBox
from kivy.uix.popup import Popup
from kivy.uix.scrollview import ScrollView
from kivy.uix.filechooser import FileChooserListView
from kivy.properties import ObjectProperty
class OpeningPage(FloatLayout):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.but = RoButton(text = 'START', pos = (350,100), font_size=14, size=(100,60), size_hint=(None,None))
self.add_widget(self.but)
class RoButton(Button):
butt = ObjectProperty()
def __init__(self, **kwargs):
super(RoButton, self).__init__(**kwargs)
text = self.text
with self.canvas:
# Color(1., 0, 0)
self.butt = RoundedRectangle( size= self.size, pos = self.pos, radius =[400])
class UI(App):
def build(self):
self.screen_manager = ScreenManager()
self.opening_page = OpeningPage()
screen = Screen(name ='Opening_Page')
screen.add_widget(self.opening_page)
self.screen_manager.add_widget(screen)
return self.screen_manager
if __name__ == '__main__':
the_app = UI()
the_app.run()
Everytime I try to make a circular button using this code I get a box behind the circle. I tried doing self.canvas.before but still no luck if possible could answers be in python rather than .kv language thanks.
Attached image of problem]1
The box you see is the normal Button image. If you don't want that, probably don't use a Button, instead use class RoButton(ButtonBehavior, Widget):.
Im trying to display a mapview on my naviwindow. However, i dont really know how to implement the class MapviewApp to the naviwindow. Any help would be appreciated since im new to kivy !!
.py file
from kivy.garden.mapview import MapView, MapMarker
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
KV = """
WindowManager:
NaviWindow:
<NaviWindow>:
Label:
text:"hi"
"""
class MapViewApp(App):
def build(self):
map = MapView(zoom=18, lat=1.3099, lon=103.7775, double_tap_zoom = True)
marker_1 = MapMarker(lat=1.3099, lon=103.7775)
map.add_marker(marker_1)
return map
class WindowManager(ScreenManager):
pass
class NaviWindow(Screen):
pass
class MyMainApp(App):
def build(self):
return Builder.load_string(KV)
if __name__ == "__main__":
MyMainApp().run()
How to get access to different widgets in python kivy?
from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.button import Button
from kivy.uix.textinput import TextInput
from kivy.uix.label import Label
class kxApp(App):
def build(self):
gl_main = GridLayout(rows=2,padding=5, spacing=5)
gl_left = GridLayout(padding=5, spacing=5)
gl_middle = GridLayout(padding=5, spacing=5)
gl_right = GridLayout(padding=5, spacing=5)
gl_main.add_widget(gl_left)
gl_main.add_widget(gl_middle)
gl_main.add_widget(gl_right)
gl_left.add_widget(TextInput(text='Input Here'))
gl_middle.add_widget(Label(text='Just Label'))
gl_right.add_widget(Button(text='Remove Input Field', on_press killFunc))
def killFunc(self,obj):
#how to get access to TextInput() and remove it?
kxApp().run()
What is the natural way to 'get' widget to manipulate it?
By saving a reference to the TextInput, you can simply use remove_widget:
from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.button import Button
from kivy.uix.textinput import TextInput
from kivy.uix.label import Label
class kxApp(App):
def build(self):
gl_main = GridLayout(rows=2,padding=5, spacing=5)
gl_left = GridLayout(cols=1, padding=5, spacing=5)
gl_middle = GridLayout(cols=1, padding=5, spacing=5)
gl_right = GridLayout(cols=1, padding=5, spacing=5)
gl_main.add_widget(gl_left)
gl_main.add_widget(gl_middle)
gl_main.add_widget(gl_right)
self.text_input = TextInput(text='Input Here')
gl_left.add_widget(self.text_input)
gl_middle.add_widget(Label(text='Just Label'))
gl_right.add_widget(Button(text='Remove Input Field', on_press=self.killFunc))
return gl_main
def killFunc(self,obj):
self.text_input.parent.remove_widget(self.text_input)
kxApp().run()
I'm having issues with parsing a data structure to a widget in Kivy, which would then access the structure and be able to show a value on the screen be updated continuously via a clock interval (not sure of a better to do this yet).
I have highlighted the issues in the (non-working) code below:
main.py
from kivy.app import App
from test import TestWidget
class TestApp(App):
def build(self):
testStructTable = {'randomVal1': 1, 'testVal': 2, 'randomVal2': 3}
# Issue here parsing the table like this?
return TestWidget(testStructTable)
if __name__ == '__main__':
TestApp().run()
test.py
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.relativelayout import RelativeLayout
from kivy.properties import NumericProperty
class TestWidget(RelativeLayout):
def __init__(self, testStructTable, **kwargs):
super(TestWidget, self).__init__(**kwargs)
Builder.load_file('test.kv')
sm = ScreenManager()
sm.add_widget(MainScreen(name='MainScreen'))
self.add_widget(sm)
# Error accessing the table
print self.testStructTable
# Have the update_test_val continuously called
#Clock.schedule_interval(MainScreen.update_test_val(testStructTable), 1 / 60)
class MainScreen(Screen):
def __init__(self, **kwargs):
testVal = NumericProperty(0)
def update_test_val(self, testStructTable):
# Get testVal from testStructTable
# Something like:
# self.testVal = testStructTable.testVal + 1 ?
self.testVal = self.testVal + 1
test.kv
<MainScreen>:
FloatLayout:
Label:
text: str(root.testVal)
font_size: 80
My aim is to have the testVal constantly updating on the screen by accessing that data structure, however I am currently unable to achieve this, can you please advise?
In your __init__ method you're passing testStructTable and then you're trying to access self.testStructTable which does not exist untill you explicitly make an assignment:
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.relativelayout import RelativeLayout
from kivy.properties import NumericProperty
class TestWidget(RelativeLayout):
def __init__(self, testStructTable, **kwargs):
super(TestWidget, self).__init__(**kwargs)
print(testStructTable)
self.testStructTable = testStructTable
print(self.testStructTable)
class TestApp(App):
def build(self):
testStructTable = {'randomVal1': 1, 'testVal': 2, 'randomVal2': 3}
# Issue here parsing the table like this?
return TestWidget(testStructTable)
if __name__ == '__main__':
TestApp().run()