I'm trying to get this kv. file to run, but it throws the error "Invalid indentation (too many levels)". For the life of me, I don't understand why. Im suspicious that its the way I am nesting the layouts within the kv. file, but I'm not sure. Any help/critique would be appreciated!
.py file:
from kivy.app import App
import tarot
from kivy.uix.widget import Widget
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.gridlayout import GridLayout
class selectCard(BoxLayout):
def __init__(self, *args, **kwargs):
super(selectCard,self).__init__(*args,**kwargs)
self.my_text = "Background.png"
def on_click(self):
if self.my_text == "Background.png":
self.my_text = tarot.read().one()
self.ids.card_image.source = "Cards\\" + self.my_text + ".png"
print(self.my_text)
else:
self.my_text = "Background.png"
self.ids.card_image.source = "Background.png"
print(self.my_text)
class layout(FloatLayout):
pass
class TarotApp(App):
def build(self):
return selectCard()
TarotApp().run()
.kv file:
<layout>
canvas.before:
Color:
rgba: 0, 1, 0, 1
Rectangle:
pos: self.pos
size: self.size
<seletCard>
layout:
Button:
normal: root.my_text
on_release: root.on_click()
background_color: 1,1,1,1
size_hint: (1,1)
pos_hint: {'center_x':.5,'center_y':.5}
Image:
source: root.my_text
id: card_image
pos: self.parent.pos
size: self.parent.size
#background_color: self.parent.background_color
stretch: True
Button:
normal: root.my_text
on_release: root.on_click()
background_color: 1,1,1,1
#size_hint: (1,1)
pos_hint: {'center_x':.5,'center_y':.5}
Image:
source: root.my_text
id: card_image
pos: self.parent.pos
size: self.parent.size
background_color: self.parent.background_color
stretch: True
I don't think this is an indentation problem. Am I referencing something incorrectly?
Related
I´m learning kivy, and it has passed 3 weeks since i face this problem without encounter a solution, so i hope any of u guys could help me, i would appreciate it.
I have a main file:
from app import MyProgramApp
if __name__ == "__main__":
winapp = MyProgramApp()
winapp.run()
from where i start my app. Then i have a directory called "app", inside there is the following "init.py" file.
from kivy.app import App
from kivy.utils import QueryDict, rgba
from kivy.core.window import Window
from .view import MainWindow
Window.minimum_width = 500
Window.minimum_height = 650
Window.maximize()
class MyProgramApp(App):
colors = QueryDict()
colors.primary = rgba('#2D9CDB')
colors.secondary = rgba('#16213E')
colors.succes = rgba('#1FC98E')
colors.warning = rgba('#F2C94C')
colors.danger = rgba('#E85757')
colors.grey_dark = rgba('#C4C4C4')
colors.grey_light = rgba('#F5F5F5')
colors.black = rgba('#A1A1A1')
colors.white = rgba('#FFFFFF')
def build(self):
return MainWindow()
Same folder app, i have the following "view.py".
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.behaviors import ToggleButtonBehavior
from kivy.properties import StringProperty
from kivy.uix.screenmanager import ScreenManager
class MainWindow(BoxLayout):
username = StringProperty("Usuario")
def __init__(self, **kw):
super().__init__(**kw)
def on_press_home(self):
self.ids.scrn_mngr.current = "scrn_home"
class ViewManager(ScreenManager):
def __init__(self, **kw):
super().__init__(**kw)
class NavTab(ToggleButtonBehavior, BoxLayout):
text = StringProperty('')
icon = StringProperty('')
def __init__(self, **kw):
super().__init__(**kw)
and finally for that folder i have "myprogram.kv"
#:kivy 2.1.0
#:import Home views.home.Home
<MainWindow>:
spacing: dp(8)
canvas.before:
Color:
rgba: app.colors.white
Rectangle:
pos: self.pos
size: self.size
# NAVIGATION BAR
BoxLayout:
id: nav_menu
size_hint_x: .2
orientation: "vertical"
size_hint_min_x: dp(100)
# LOGO
BoxLayout:
id: logo_nbox
size_hint_y: .1
size_hint_min_y: dp(70)
padding: dp(16)
AnchorLayout:
anchor_x: "right"
size_hint_x: None
width: dp(52)
halign: "left"
Label:
text: "COMPANY"
halign: "center"
BoxLayout:
orientation: "vertical"
Label:
text: "COMPANY"
halign: "center"
Label:
text: "Phrase"
halign: "center"
# OPTIONS
GridLayout:
id: tabs_box
cols: 1
spacing: dp(4)
size_hint_y: .5
canvas.before:
Color:
rgba: app.colors.grey_dark
Rectangle:
pos: self.pos
size: [self.size[0], dp(1)]
NavTab:
text: "Home"
state: "down"
on_press: root.on_press_home()
# BODY
BoxLayout:
size_hint_x: .8
spacing: dp(8)
orientation: "vertical"
padding: [dp(16), dp(8), dp(12), dp(8)]
canvas.before:
Color:
rgba: app.colors.grey_light
Rectangle:
pos: self.pos
size: self.size
# SCREENS
BoxLayout:
ViewManager:
id: scrn_mngr
<ViewManager>:
Screen:
name: "scrn_home"
Home:
id: home
<NavTab>:
background_normal: ""
background_down: ""
background_color: [0,0,0,0]
group: "tabs"
size_hint_y: None
height: dp(45)
spacing: dp(4)
canvas.before:
Color:
rgba: [0,0,0,0] if self.state == "normal" else rgba("#E1F1FF")
Rectangle:
pos: self.pos
size: self.size
Color:
rgba: [0,0,0,0] if self.state == "normal" else app.colors.primary
Rectangle:
pos: [self.pos[0]+self.size[0]-dp(1), self.pos[1]]
size: [dp(8), self.size[1]]
Label:
halign: "left"
valign: "middle"
text: root.text
color: app.colors.grey_dark if root.state == "normal" else app.colors.primary
Then i got another folder called "views" inside i have another folder called "home", inside home we encounter 3 files "init.py", "home.kv", "home.py". the first one "init.py" is the following.
from .home import Home
then we got "home.kv".
#:kivy 2.1.0
<Home>:
orientation: "vertical"
Label:
size_hint_y: .1
text: "Other"
Button:
size_hint_y: .1
text: "popup"
on_press: root.open_popup()
BoxLayout:
size_hint_y: .8
id: home_box
<SomePopup>:
title: "SOME TITLE"
title_align: "center"
title_color: app.colors.primary
size_hint: .25, .8
size_hint_min_x: dp(200)
pos_hint: {"x": .1, "top": .9}
BoxLayout:
orientation: "vertical"
padding: [dp(0), dp(12), dp(0), dp(12)]
Label:
text: "Some text"
Button:
text: "create buttons on box"
on_press: root.modify_home_box()
and finally and the problem that i´m facing is whit the following file "home.py"
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.factory import Factory
from kivy.uix.popup import Popup
from kivy.uix.button import Button
from kivy.app import App
Builder.load_file('views/home/home.kv')
class Home(BoxLayout):
def __init__(self, **kwargs):
super().__init__(**kwargs)
def open_popup(self):
Factory.SomePopup().open()
class SomePopup(Popup):
def __init__(self, **kw):
super().__init__(**kw)
def modify_home_box(self):
my_app = App.get_running_app().root
my_box = my_app.ids.home.ids.home_box
custom_button = Button(
text = "something"
)
my_box.add_widget(custom_button)
That i´m trying to do is actually modify "home_box" with is store on ids Home dictionary, i also try with ObjectProperty (but that gives and Attribute Error, since i only could read propertys but doesnt modify it), instance of a new Home class doesnt work... searching for current app in App appear doesnt work since Home is store i think on screenManager...
I need add a button or some widget to "home_box" from outside class "SomePopup". I also drop here a repository on github with the whole code. github_repo
I don't know how to solve my issue, and i try with the resources available here on stack as well other net places... any help would be appreciate.
Just a very complicated path to the widget of interest. In your modify_home_box() method, try replacing:
my_app = App.get_running_app().root
my_box = my_app.ids.home.ids.home_box
with:
my_app = App.get_running_app().root
my_box = my_app.ids.scrn_mngr.ids.home.ids.home_box
I am trying to print an input given by a user but all I get is: < ObjectProperty name=input >
I can't use Text Input in my py because python quits if I try to run a program with it installed. I have tried putting the popup in the 'test' class but it just comes up with a different error.
Any help is appreciated,
Thank you.
Here is my code:
In my py:
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.popup import Popup
class MyPopup(Popup):
pass
class Test(Widget):
pass
class TestApp(App):
def build(self):
return Test()
def Process(self):
text = MyPopup.input
print(text)
if __name__ == '__main__':
TestApp().run()
and in my kv:
#:import Factory kivy.factory.Factory
<MyPopup#Popup>
input: text
auto_dismiss: True
size_hint: 0.4, 0.4
TextInput:
id: text
hint_text: 'insert text'
multiline: False
on_text_validate: app.Process()
<Test>:
canvas:
Color:
rgba: 0, 0, 0, 0
Rectangle:
pos: 0, 0
size: self.width, self.height - self.height/6
Color:
rgba: 1, 1, 1, 0.1
Rectangle:
pos: 0, 0
size: self.width/2 + self.width/10, self.height - self.height/6
Color:
rgba: 1, 1, 1, 1
Rectangle:
pos: 0, self.height - self.height/6
size: self.width, self.height/6
Button:
id: GL
text: 'In here'
pos: 0 , root.height - root.height/6
on_parent: GLdropdown.dismiss()
on_release: GLdropdown.open(self)
size_hint_y: None
height: root.height/6
width: root.width/7
DropDown:
id: GLdropdown
on_select: btn.text = '{}'.format(args[1])
Button:
id: 'AV'
text: 'press me'
size_hint_y: None
height: 50
on_release: Factory.MyPopup().open()
If you change:
on_text_validate: app.Process()
to:
on_text_validate: app.Process(self.text)
And change the Process() method to:
def Process(self, text):
print(text)
I think it will work as you want.
The problem is that the line:
text = MyPopup.input
makes text a reference to the ObjectProperty of the class MyPopup. What you really want is a reference to the text of the TextInput, which is simply self.text in the TextInput.
Any assistance is much appreciated.
Here's an example code to show the problem,
when the ('Press me') button is pressed and the widget resized(white box come within view), the TabbedPanel redraws like a glitch (even though its not).
I've tried changing the layout order and toyed a bit with the animation, no
I wish to prevent that blinking behaviour of the tabbedpanel on the left.
import kivy
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.animation import Animation
from kivy.lang import Builder
Builder.load_string('''
<Main>:
BoxLayout:
orientation:'vertical'
BoxLayout:
id: main_screen
orientation: 'horizontal'
TabbedPanel:
do_default_tab: False
tab_pos: 'left_top'
tab_width: main_screen.height/4
TabbedPanelItem:
text: 'four'
TabbedPanelItem:
text: 'three'
TabbedPanelItem:
text: 'two'
TabbedPanelItem:
text: 'one'
BoxLayout:
id: swidget
slide: 0
size_hint: None, None
height: main_screen.height
width: self.slide
canvas:
Color:
rgba: 1,1,1,1
Rectangle:
pos: self.pos
size: self.size
Button:
size_hint_y: None
height: '33dp'
text: 'Press me'
on_release: root.display_widget(swidget)
''')
class Main(BoxLayout):
def __init__(self, **kwargs):
super(Main, self).__init__(**kwargs)
def display_widget(self, widget):
swidget = widget
if swidget.slide == 0:
anim = Animation(slide=105, duration=0.6)
anim.start(widget)
else:
anim = Animation(slide=0, duration=0.6)
anim.start(widget)
class TabbedApp(App):
def build(self):
return Main()
TabbedApp().run()
Add AnchorLayout to be the parent of swidget / BoxLayout and when the animation starts, it won't impact the instantiated TabbedPanel.
Snippets
AnchorLayout:
anchor_x: 'right'
anchor_y: 'top'
size_hint_x: None
width: 0
BoxLayout:
id: swidget
slide: 0
size_hint_x: None
width: self.slide
canvas:
Color:
rgba: 1,1,1,1
Rectangle:
pos: self.pos
size: self.size
I'm new to kivy , I'm trying to write an application using kivy in python, I got struck at one point where i have to read text from textinput whenever it is changed and based on that i want to implement my button's functionality - I have gone through all the documentation but i couldn't figure out how to do it - Can any body tell me how can I resolve this or am I missing something?
from __future__ import print_function
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.core.image import Image
from kivy.uix.floatlayout import FloatLayout
from kivy.graphics import *
from kivy.uix.anchorlayout import AnchorLayout
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.uix.popup import Popup
from kivy.properties import ObjectProperty
import walascan
from kivy.clock import Clock
import os
kv = """
<KartScan>:
IntroScreen:
<IntroScreen#Screen>:
orientation: 'horizontal'
name: 'introscreen'
canvas.before:
Rectangle:
pos: self.pos
size: self.size
source: 'index.png'
AnchorLayout:
anchor_x: 'center'
anchor_y: 'center'
BoxLayout:
orientation:'horizontal'
size_hint: .5, .1
canvas:
Color:
rgb: 1, 1, 1
Rectangle:
pos: self.pos
size: self.size
spacing: 20
pos_hint: {'center_x':.8, 'center_y': .8}
AnchorLayout:
anchor_x: 'left'
size_hint_x: .5
TextInput:
id: waybill
width: 20
text: "Enter Waybill No."
multiline: False
height: self.minimum_height
size_hint_y: None
font_size: 30
focus: True
on_text_validate: app.on_waybill()
AnchorLayout:
anchor_x: 'right'
size_hint_x: None
Button:
size_hint: None, None
height: 50
width: self.texture_size[0]
padding: 10, 10
text: "Add"
on_press:app.buttonClicked()
on_release: root.current = 'mainpage'
AnchorLayout:
anchor_x: 'right'
size_hint_x: None
Button:
size_hint: None, None
height: 50
width: self.texture_size[0]
padding: 10, 10
text: "Compare"
on_press:app.buttonClicked()
on_release: root.current = 'mainpage'
"""
Builder.load_string(kv)
waybill = TextInput(text="Enter Waybill No.", multiline=False)
class KartScan(FloatLayout):
def __init__(self, **kwargs):
super(KartScan, self).__init__(**kwargs)
self.register_event_type('on_text_validate')
def on_text(self, *args):
print('new value is ', waybill.text)
def on_text_validate(self):
pass
def on_focus(self, obj, focused):
if not focused:
self.dispatch('on_text_validate')
class KartScanApp(App):
def build(self):
return KartScan()
def buttonClicked(self):
popup = Popup(title='Result',
content=Label(text=self.on_waybill()),
size_hint=(None, None), size=(100, 100))
popup.bind()
popup.open()
def getwlbtstate(self):
return walascan.mainAntennas()
def on_waybill(self):
waybill.bind(text=KartScan.on_text_validate)
# popup = Popup(title='Result',
# content=Label(text=waybill.text),
# size_hint=(None, None), size=(100, 100))
# popup.bind()
# popup.open()
return waybill.text
if __name__ == '__main__':
KartScanApp().run()
kv file
TextInput:
on_text: print(self.text)
You could use on_text to call a function when the text changes. I think it sometimes even triggers when no change has occured.
TextInput has a text property, and in kivy, all properties have associated on_xxx events, that you can bind to to react to them, so when reading the doc, even if it's not explicitly mentionned for them, everytime you see something is defined as a Property (or any subclass of it, like StringPropertyNumericProperty,ObjectProperty,AliasProperty`).
TextInput:
on_text: do_something(self.text)
or in python
t = TextInput(text='', on_text=do_something)
or
t = TextInput(text='')
t.bind(on_text=do_something)
I am trying to build a kivy app and I need to put my .py file and .kv file in a file called main.py. How do I do this? Thank you.
You will need to use Builder for this. Docs
The below code illustrate it.
from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.lang import Builder
Builder.load_string("""
#:import hex kivy.utils.get_color_from_hex
<Root>:
cols: 2
canvas:
Color:
rgba: 1, 1, 1, 1
Rectangle:
pos: self.pos
size: self.size
Label:
canvas.before:
Color:
rgb: 39/255., 174/255., 96/255.
Rectangle:
pos: self.pos
size: self.size
text: "rgb: 39/255., 174/255., 96/255."
Label:
canvas.before:
Color:
rgba: 39/255., 174/255., 96/255., 1
Rectangle:
pos: self.pos
size: self.size
text: "rgba: 39/255., 174/255., 96/255., 1"
Label:
canvas.before:
Color:
hsv: 145/360., 77.6/100, 68.2/100
Rectangle:
pos: self.pos
size: self.size
text: "hsv: 145/360., 77.6/100, 68.2/100"
Label:
canvas.before:
Color:
rgba: hex('#27ae60')
Rectangle:
pos: self.pos
size: self.size
text: "rgba: hex('#27ae60')"
""")
class Root(GridLayout):
pass
class ColorusageApp(App):
def build(self):
return Root()
if __name__ == "__main__":
ColorusageApp().run()
You can embed your .kv file in python like this
Builder.load_string("""
<MyWidget>:
...
""")
class MyApp(App):
...
for more info click here