Kivy importing Python variables into inline KV - python

I've been banging my head off this particular wall for days now. None of the relevant articles here have worked, so I really need to know where I'm going wrong. The relevant sections of code are:
def print_scb(myscb):
print(myscb)
scb_string = ''
scb_list = [ 'Combat' , 'Communication' , 'Manipulation' , 'Mental' , 'Perception', 'Physical' ]
for s in scb_list:
zz = str(myscb[s])
scb_string = scb_string + s + " " + zz + "% "
return scb_string
And the inline KV section is:
<CharacterSheet>:
BoxLayout:
orientation: 'vertical'
Label:
text:'Stats'
Label:
text: app.print_stats()
Label:
text:'Rolls'
Label:
text: app.print_rolls()
Label:
text:'SCM'
Label:
text: app.print_scm()
Label:
text:'SCB'
Label:
text: app.print_scb()
Button:
text:'Quit'
on_press: sys.exit()
Button:
text:'Back to Start'
on_press: root.manager.current = 'welcome'
""")
The program crashes with:
kivy.lang.BuilderException: Parser: File "<inline>", line 114:
...
112: text:'SCB'
113: Label:
>> 114: text: app.print_scb()
115: Button:
116: text:'Quit'
...
BuilderException: Parser: File "<inline>", line 114:
...
112: text:'SCB'
113: Label:
>> 114: text: app.print_scb()
115: Button:
116: text:'Quit'
...
AttributeError: 'NoneType' object has no attribute 'bind'
File "/usr/lib64/python3.4/site-packages/kivy/lang.py", line 1742, in create_handler
return eval(value, idmap), bound_list
File "<string>", line 114, in <module>
File "/usr/lib64/python3.4/site-packages/kivy/lang.py", line 935, in __getattribute__
object.__getattribute__(self, '_ensure_app')()
File "/usr/lib64/python3.4/site-packages/kivy/lang.py", line 930, in _ensure_app
app.bind(on_stop=lambda instance:
File "/usr/lib64/python3.4/site-packages/kivy/lang.py", line 2115, in _apply_rule
rctx['ids'])
File "/usr/lib64/python3.4/site-packages/kivy/lang.py", line 1747, in create_handler
cause=tb)
The whole code has been posted to dpaste at BrpGui.py
The print_scb() functions returns a string.
Any ideas where I'm going wrong?
Colin

As you mentioned in the comments.
print_scb is not a global function. It is defined in the CharacterSheet(Screen): class.
When you defined the function you forgor self.
So instead of def print_scb(myscb): it shall be def print_scb(self, myscb):
Also in your kv file, dont use app.print_scb() but root.print_scb()
Since it belongs to that class.
But since your function wants a parameter, it will throw an error. So you need to call it with a parameter. like this root.print_scb(some_variable)
From the docs https://kivy.org/docs/guide/lang.html -
There are three keywords specific to Kv language:
app: always refers to the instance of your application.
root: refers to the base widget/template in the current rule
self: always refer to the current widget

Related

How to change the anchor value in MDFloatingActionButtonSpeedDial in KivyMD?

I have been working with kivymd to develop a mobile application. But I was having a problem regarding MDFloatingActionButtonSpeedDial. I wanted to set the anchor value in MDFloatingActionButtonSpeedDial to "left" for some buttons and "right" for some buttons. So I modified the class of MDFloatingActionButtonSpeedDial that is in the module "kivymd.uix.button" and added some more options in 'anchor' which assumes OptionProperty. Along with it I also added the methods required for the applied changes. The changes in acnhor are:-
anchor = OptionProperty('right',option=["right","left"])
And the changes in the methods are:-
def set_pos_labels(self, widget):
"""Sets the position of the floating labels."""
if self.anchor == "right":
widget.x = Window.width - widget.width - dp(86)
elif self.anchor == "left":
widget.x = widget.width + dp(86)
def set_pos_root_button(self, instance):
"""Sets the position of the root button."""
if self.anchor == "right":
instance.y = dp(20)
instance.x = Window.width - (dp(56) + dp(20))
elif self.anchor == "left":
instance.y = dp(20)
instance.x = (dp(56) + dp(20))
def set_pos_bottom_buttons(self, instance):
"""Sets the position of the bottom buttons in a stack."""
if self.anchor == "right":
if self.state != "open":
instance.y = instance.height / 2
instance.x = Window.width - (instance.height + instance.width / 2)
elif self.anchor == "left":
if self.state != "open":
instance.y = instance.height / 2
instance.x = (instance.height + instance.width / 2)
I have added the left anchor property as the right anchor was present by default.
The Builder string that I have written is as follows:-
MDFloatingActionButtonSpeedDial:
data : app.data_download
rotation_root_button : True
id : download_button
icon: 'download'
anchor: 'left'
MDFloatingActionButtonSpeedDial:
data : app.data_return
rotation_root_button: True
icon : 'arrow-left'
anchor: 'right'
Now whenever I tried to set the anchor property to 'left' other than the default option(right) in my builder string file the program returns an error. I want to inform if I set the default value of anchor to left then I get the error for setting the anchor to right and when I set the default value of anchor to right then I get the error for setting the anchor to left. The error that that I am getting is:-
Traceback (most recent call last):
File "C:\Users\user\Anaconda3\lib\site-packages\kivy\lang\builder.py", line 700, in _apply_rule
setattr(widget_set, key, value)
File "kivy\weakproxy.pyx", line 35, in kivy.weakproxy.WeakProxy.__setattr__
File "kivy\properties.pyx", line 497, in kivy.properties.Property.__set__
File "kivy\properties.pyx", line 541, in kivy.properties.Property.set
File "kivy\properties.pyx", line 532, in kivy.properties.Property.set
File "kivy\properties.pyx", line 1252, in kivy.properties.OptionProperty.check
ValueError: MDFloatingActionButtonSpeedDial.anchor is set to an invalid option 'left'. Must be one
of: []
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "onlinecv2.py", line 500, in <module>
ScanIt().run()
File "C:\Users\user\Anaconda3\lib\site-packages\kivy\app.py", line 829, in run
root = self.build()
File "onlinecv2.py", line 435, in build
camerascreen = Builder.load_string(screen_helper)
File "C:\Users\user\Anaconda3\lib\site-packages\kivy\lang\builder.py", line 405, in load_string
rule_children=rule_children)
File "C:\Users\user\Anaconda3\lib\site-packages\kivy\lang\builder.py", line 707, in _apply_rule
e), cause=tb)
kivy.lang.builder.BuilderException: Parser: File "<inline>", line 154:
...
152: id : download_button
153: icon: 'download'
>> 154: anchor: 'left'
155:
156:
...
ValueError: MDFloatingActionButtonSpeedDial.anchor is set to an invalid option 'left'. Must be one
of: []
File "C:\Users\user\Anaconda3\lib\site-packages\kivy\lang\builder.py", line 700, in _apply_rule
setattr(widget_set, key, value)
File "kivy\weakproxy.pyx", line 35, in kivy.weakproxy.WeakProxy.__setattr__
File "kivy\properties.pyx", line 497, in kivy.properties.Property.__set__
File "kivy\properties.pyx", line 541, in kivy.properties.Property.set
File "kivy\properties.pyx", line 532, in kivy.properties.Property.set
File "kivy\properties.pyx", line 1252, in kivy.properties.OptionProperty.check
The output that I am getting (which is undesirable) when i dont set any anchor value in my kivy file is as:-
I only get the floating button in the right. But the output that I desire is I wanted two floating buttons to be present on both side of the screen i.e. left as well as right. But I am getting only on one side and so i started to change the module but ended up with an error.
So, I would be glad if you can provide me an solution to solve this error so that I can use both the anchor properties 'left' and 'right'.

Cannot control the value of opacity

I have a Class level boolean variable which speaks with all the classes and widget in each class change depending on weather or not this value is true. Opacity is throwing the below error when I try to execute. I've tried AsyncImages but it given a loading logo which I am trying to avoid.
Below is the snippet of the code
Python File:
class MainScreen(Screen):
pass
class SecondScreen(Screen):
pass
class TestApp(App):
ABS_OPACITY=BooleanProperty(True)
def test(self):
print "Hello"
def build(self):
return presentation
Kivy file -
ScreenManagement:
MainScreen:
SecondScreen:
<MainScreen>:
name: "Main"
FloatLayout:
Button:
font_size:12
size_hint: 0.07, 0.05
text: "AC"
on_click:app.ABS_OPACITY=not app.ABS_OPACITY
pos_hint: {"right":0.93,"left":0.30, "bottom":0.1, "top": 0.93}
Image:
source: "xyz/image.png"
pos_hint:{"top":0.955}
opacity:1 if app.ABS_OPACITY else 0
Image:
source: "abc/image.png"
pos_hint:{"top":0.955}
opacity:0 if app.ABS_OPACITY else 1
<SecondScreen>:
name: "Second"
FloatLayout:
Button:
font_size:12
size_hint: 0.07, 0.05
text: "AC"
on_click:on_click:app.ABS_OPACITY=not app.ABS_OPACITY
pos_hint: {"right":0.93,"left":0.30, "bottom":0.1, "top": 0.93}
Image:
source: "xyz/image"
pos_hint:{"top":0.955}
opacity:1 if app.ABS_OPACITY else 0
Image:
source: "abc/image.png"
pos_hint:{"top":0.955}
opacity:0 if app.ABS_OPACITY else 1
The above is the error I am facing when I do the same..
Traceback (most recent call last):
File "testapp.py", line 412, in <module>
presentation = Builder.load_file ("main.kv")
File "/home/pi/.local/lib/python2.7/site-packages/kivy/lang/builder.py", line 301, in load_file
return self.load_string(data, **kwargs)
File "/home/pi/.local/lib/python2.7/site-packages/kivy/lang/builder.py", line 405, in load_string
rule_children=rule_children)
File "/home/pi/.local/lib/python2.7/site-packages/kivy/lang/builder.py", line 657, in _apply_rule
root=rctx['ids']['root'], rule_children=rule_children)
File "/home/pi/.local/lib/python2.7/site-packages/kivy/uix/widget.py", line 469, in apply_class_lang_rules
rule_children=rule_children)
File "/home/pi/.local/lib/python2.7/site-packages/kivy/lang/builder.py", line 538, in apply
rule_children=rule_children)
File "/home/pi/.local/lib/python2.7/site-packages/kivy/lang/builder.py", line 707, in _apply_rule
e), cause=tb)
kivy.lang.builder.BuilderException: Parser: File "/home/pi/Downloads/motormind/main.kv", line 161:
...
159: source: "UI_UX/blue/mainpage/abs.png"
160: pos_hint:{"top":0.955}
>> 161: opacity:0 if app.ABS_OPACITY else 1
162: #Park Lights On
163: Image:
...
BuilderException: Parser: File "/home/pi/Downloads/motormind/main.kv", line 161:
...
159: source: "UI_UX/blue/mainpage/abs.png"
160: pos_hint:{"top":0.955}
>> 161: opacity:0 if app.ABS_OPACITY else 1
162: #Park Lights On
163: Image:
...
AttributeError: 'NoneType' object has no attribute 'bind'
File "/home/pi/.local/lib/python2.7/site-packages/kivy/lang/builder.py", line 249, in create_handler
return eval(value, idmap), bound_list
File "/home/pi/Downloads/motormind/main.kv", line 161, in <module>
opacity:0 if app.ABS_OPACITY else 1
File "/home/pi/.local/lib/python2.7/site-packages/kivy/lang/parser.py", line 75, in __getattribute__
object.__getattribute__(self, '_ensure_app')()
File "/home/pi/.local/lib/python2.7/site-packages/kivy/lang/parser.py", line 70, in _ensure_app
app.bind(on_stop=lambda instance:
File "/home/pi/.local/lib/python2.7/site-packages/kivy/lang/builder.py", line 692, in _apply_rule
rctx['ids'])
File "/home/pi/.local/lib/python2.7/site-packages/kivy/lang/builder.py", line 254, in create_handler
cause=tb
This error is typical of calling Builder.load_file() for a kv file that is creating Widgets and referencing the app before an App is defined. Try calling Builder.load_file() in the build() method of the App.
Another way to fix this is to use a <ScreenManagerment> rule in the kv file and then do
return ScreenManagement()
in your build() method.

kivy - textinput from kv to py - import data

I'm trying to get the data from a simple textinput that is in my kv file and use the information in my python file.
but i keep getting the same error.
this error happens when i press a button and the function try to run looks like its trying to get the information from the text_location widget
thank you in advance.
class ScatterTextWidget(BoxLayout):
def initialize_request(self):
''' Initial analysis and control flow of the class '''
location = self.ids.input_location
date = S.ids.input_date
time_raw = ScatterTextWidget.ids.input_time
print(f'{location} - {date} - {time_raw}')
class HistoricalApp(App):
def build(self):
return ScatterTextWidget()
if __name__ == "__main__":
HistoricalApp().run()
the kivy file called "historical.kv"
i reduce it because is kind of long
<ScatterTextWidget>:
BoxLayout:
canvas.before:
Color:
rgb: utils.get_color_from_hex('#01183f')
Rectangle:
pos: self.pos
size: self.size
size_hint_y: None
height: 40
valign: 'middle'
TextInput:
id:text_location
width: 200
id: input2
font_size: 15
size_hint_y: None
height:40
TextInput:
id:input_date
width: 200
id: input1
font_size: 15
size_hint_y: None
height: 40
TextInput:
id:input_time
width: 200
id: input1
font_size: 15
size_hint_y: None
height: 40
the error i receive is
File "kivy\properties.pyx", line 838, in
kivy.properties.ObservableDict.__getattr__
KeyError: 'text_location'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:/Users/IBKCo/Desktop/Git Programs/TimeStationHistoricalRecords/MainGui.py", line 77, in <module>
HistoricalApp().run()
File "C:\Users\IBKCo\Desktop\Git Programs\TimeStationHistoricalRecords\pdEnv\lib\site-packages\kivy\app.py", line 826, in run
runTouchApp()
File "C:\Users\IBKCo\Desktop\Git Programs\TimeStationHistoricalRecords\pdEnv\lib\site-packages\kivy\base.py", line 502, in runTouchApp
EventLoop.window.mainloop()
File "C:\Users\IBKCo\Desktop\Git Programs\TimeStationHistoricalRecords\pdEnv\lib\site-packages\kivy\core\window\window_sdl2.py", line 727, in mainloop
self._mainloop()
File "C:\Users\IBKCo\Desktop\Git Programs\TimeStationHistoricalRecords\pdEnv\lib\site-packages\kivy\core\window\window_sdl2.py", line 460, in _mainloop
EventLoop.idle()
File "C:\Users\IBKCo\Desktop\Git Programs\TimeStationHistoricalRecords\pdEnv\lib\site-packages\kivy\base.py", line 340, in idle
self.dispatch_input()
File "C:\Users\IBKCo\Desktop\Git Programs\TimeStationHistoricalRecords\pdEnv\lib\site-packages\kivy\base.py", line 325, in dispatch_input
post_dispatch_input(*pop(0))
File "C:\Users\IBKCo\Desktop\Git Programs\TimeStationHistoricalRecords\pdEnv\lib\site-packages\kivy\base.py", line 291, in post_dispatch_input
wid.dispatch('on_touch_up', me)
File "kivy\_event.pyx", line 707, in kivy._event.EventDispatcher.dispatch
File "C:\Users\IBKCo\Desktop\Git Programs\TimeStationHistoricalRecords\pdEnv\lib\site-packages\kivy\uix\behaviors\button.py", line 179, in on_touch_up
self.dispatch('on_release')
File "kivy\_event.pyx", line 703, in kivy._event.EventDispatcher.dispatch
File "kivy\_event.pyx", line 1214, in kivy._event.EventObservers.dispatch
File "kivy\_event.pyx", line 1098, in kivy._event.EventObservers._dispatch
File "C:\Users\IBKCo\Desktop\Git Programs\TimeStationHistoricalRecords\pdEnv\lib\site-packages\kivy\lang\builder.py", line 64, in custom_callback
exec(__kvlang__.co_value, idmap)
File "C:\Users\IBKCo\Desktop\Git Programs\TimeStationHistoricalRecords\historical.kv", line 127, in <module>
on_release: root.initialize_request()
File "C:/Users/IBKCo/Desktop/Git Programs/TimeStationHistoricalRecords/MainGui.py", line 31, in initialize_request
location = self.ids.text_location
File "kivy\properties.pyx", line 841, in kivy.properties.ObservableDict.__getattr__
AttributeError: 'super' object has no attribute '__getattr__'
thank you in advance
best,
First, you need to remove both of the id:input1 lines and the id:input2 line. Then change your initialize_request method to:
def initialize_request(self):
''' Initial analysis and control flow of the class '''
location = self.ids.text_location.text
date = self.ids.input_date.text
time_raw = self.ids.input_time.text
print(f'{location} - {date} - {time_raw}')
Note that self.ids.text_location is a reference to the TextInput widget, so you have to add .text to get its text. Same for the other TextInput widgets.

can i use for statement in .kv file?

GridLayout:
cols:
rows: root.numberoflist
for i in range(root.businfolist):
Label:
font_name: 'C:/Windows/Fonts/HYWULM'
text_size: cm(2), cm(2)
pos: self.pos
id: my_custom_label
text: root.businfolist[0]
color: [255,255,255,1]
.kv file
i want use FOR STATEMENT to .kv file and i saw the
https://kivy.org/docs/api-kivy.lang.html?highlight=statement
this page, but i don't understand.
i think indentation seems to be wrong.
what is wrong with these code?
traceback is here thank you for read my question.
Traceback (most recent call last):
File "C:/Users/mg/Desktop/Tubuc/TubucTest.py", line 58, in <module>
class Bus_Information(Screen):
File "C:/Users/mg/Desktop/Tubuc/TubucTest.py", line 60, in Bus_Information
Builder.load_string(f.read())
File "C:\Users\mg\Anaconda3\lib\site-packages\kivy\lang\builder.py", line 368, in load_string
parser = Parser(content=string, filename=fn)
File "C:\Users\mg\Anaconda3\lib\site-packages\kivy\lang\parser.py", line 392, in __init__
self.parse(content)
File "C:\Users\mg\Anaconda3\lib\site-packages\kivy\lang\parser.py", line 501, in parse
objects, remaining_lines = self.parse_level(0, lines)
File "C:\Users\mg\Anaconda3\lib\site-packages\kivy\lang\parser.py", line 605, in parse_level
level + 1, lines[i:], spaces)
File "C:\Users\mg\Anaconda3\lib\site-packages\kivy\lang\parser.py", line 615, in parse_level
'Invalid property name')
kivy.lang.parser.ParserException: Parser: File "<inline>", line 28:
...
26: rows: root.numberoflist
27:
>> 28: for i in range(root.businfolist):
29: Label:
30: font_name: 'C:/Windows/Fonts/HYWULM'
...
Invalid property name
Add import statement, #:import Label kivy.uix.label.Label
Use on_parent event to execute the for loop in kv file
Valid expressions
There are two places that accept python statements in a kv file:
after a property, which assigns to the property the result of the expression (such as the text of a button as shown above) and
after a on_property, which executes the statement when the property is updated (such as on_state).
main.py
from kivy.lang import Builder
from kivy.base import runTouchApp
runTouchApp(Builder.load_string('''
#:kivy 1.11.0
#:import Label kivy.uix.label.Label
GridLayout:
cols: 3
on_parent:
for i in range(10): txt = "Label {0}".format(i); self.add_widget(Label(text = txt, text_size=(cm(2), cm(2)), pos=self.pos,
id=txt, color=(1,1,1,1)))
'''))
Output

Kivy - How to access kivy widget in python?

I want to edit a text in a TextInput in kivy but don't know how to, I've tried this code as Ive search in the net but still no luck.
class MainApp(Screen):
def __init__(self,**kwargs):
super(MainApp,self).__init__(**kwargs)
pass
class Forms(BoxLayout):
def __init__(self, **kwargs):
super(Main,self).__init__(**kwargs)
self.ids.txtSearch.text = "new text"
class Main(App):
def build(self):
return root_widget
if __name__ == "__main__":
Main().run()
------kivy-------
<Main>:
TextInput:
id: txtSearch
this is not my whole code but I think those are what matters in the issue
this is the error:
File "C:\Users\Guest\Documents\Python\Kivy\Project\main.py", line 295, in <module>
''')
File "D:\Kivy-1.9.0-py3.4-win32-x64\kivy34\kivy\lang.py", line 1828, in load_string
self._apply_rule(widget, parser.root, parser.root)
File "D:\Kivy-1.9.0-py3.4-win32-x64\kivy34\kivy\lang.py", line 1985, in _apply_rule
self.apply(child)
File "D:\Kivy-1.9.0-py3.4-win32-x64\kivy34\kivy\lang.py", line 1872, in apply
self._apply_rule(widget, rule, rule)
File "D:\Kivy-1.9.0-py3.4-win32-x64\kivy34\kivy\lang.py", line 1986, in _apply_rule
self._apply_rule(child, crule, rootrule)
File "D:\Kivy-1.9.0-py3.4-win32-x64\kivy34\kivy\lang.py", line 1986, in _apply_rule
self._apply_rule(child, crule, rootrule)
File "D:\Kivy-1.9.0-py3.4-win32-x64\kivy34\kivy\lang.py", line 1983, in _apply_rule
child = cls(__no_builder=True)
File "C:\Users\Guest\Documents\Python\Kivy\Project\main.py", line 40, in __init__
self.ids.txtSearch.text = "new text"
File "kivy\properties.pyx", line 720, in kivy.properties.ObservableDict.__getattr__ (kivy\properties.c:10911)
AttributeError: 'super' object has no attribute '__getattr__'
To change Widgets properties in kivy you need to 'link' the widget between .py and .kv file, first in .py file:
txt_Search = ObjectProperty()
then in .kv file, in your root widget:
txt_Search: txtSearch
then assign the id to a widget (as you already did):
<Main>:
TextInput:
id: txtSearch
text: ' '
then in your .py file, you can change attributes of the widget by doing this:
self.txt_Search.text = 'New Text'
or any other attribute:
self.txt_Search.height = '30dp'
Are you sure self.ids.txtSearch exists when you try to assign a text to it? You're calling super(Main,self) one line above so I guess txtSearch is never instantiated.
Btw, it's better to init widgets in *.kv files:
<Main>:
TextInput:
id: txtSearch
text: "new text"

Categories

Resources