I have a TextInput and a button, and my aim is to be able to select some text from the TextInput and then push a button which calls a function that prints: selection_text, selection_to, and selection_from.
However, because the TextInput is not in focus when the button is pushed, the selection is lost and the function returns nothing AND/OR incorrect values.
I have seen this line of code in similar questions but I have not been able to figure out what it is meant to do, via messing with the code or looking at the TextInput docs, since I have only seen it called from within an 'on_focus' function
Clock.schedule_once(lambda dt: new_post_input.selection_text)
I have not been able to recreate the issue in an example program yet since it works when I have taken the widgets into their own program
main.py
from kivy.app import App
from kivy.properties import BooleanProperty, StringProperty
from kivy.uix.floatlayout import FloatLayout
from kivy.modules import inspector
from kivy.core.window import Window
class NewPost(FloatLayout):
buttons_disabled = BooleanProperty(False)
cancle_button_disabled = BooleanProperty(True)
preview_text = StringProperty()
def make_bold(self, new_post_input, selected):
print('Selected = ' + selected)
print('Button has been pushed')
def preview_post(self, Button, cancleButton, TextInput, Label):
#self.preview_text = ('Hello\n' + TextInput.text)
self.buttons_disabled = True
self.cancle_button_disabled = False
Label.opacity = 1
Label.pos_hint = {'center_x': 0.5, 'center_y': 0.5}
TextInput.opacity = 0
cancleButton.opacity = 1
cancleButton.pos_hint = {'center_x': 0.5, 'center_y': 0.5}
Button.opacity = 0
Button.pos_hint = {'center_x': 0.5, 'center_y': -1}
#print(TextInput.text)
def back_from_preview(self, Button, previewButton, TextInput, Label):
self.buttons_disable = False
self.cancle_button_disabled = True
Label.opacity = 0
Label.pos_hint = {'center_x': 0.5, 'center_y': -1}
TextInput.opacity = 1
Button.opacity = 0
Button.pos_hint = {'center_x': 0.5, 'center_y': -1}
previewButton.opacity = 1
previewButton.pos_hint = {'center_x': 0.5, 'center_y': 0.5}
class SelectionApp(App):
def build(self):
inspector.create_inspector(Window, SelectionApp)
SelectionApp().run()
selection.kv
PageLayout:
Label:
text: 'Swipe to the next page'
font_size: dp(50)
Label:
text: 'And again'
canvas.before:
Color:
rgba: (0,.8,.8,1)
RoundedRectangle:
size: self.size
radius: [dp(6),]
pos: self.x, self.y
NewPost:
id: new_post
canvas.after:
Color:
rgba: 0,1,0,1
Line:
width: dp(1.6)
rounded_rectangle:(self.x, self.y, self.width, self.height, dp(5))
BoxLayout:
id: main_new_post
orientation: 'vertical'
padding: '10dp', '16dp'
pos_hint: {'center_x': 0.5, 'center_y': 0.5}
canvas.before:
Color:
rgba: 0, 0, 0, 1
Rectangle:
pos: self.pos
size: self.size
AnchorLayout:
size_hint: 1, .05
anchor_x: 'right'
anchor_y: 'center'
Label:
text: 'New Post'
size_hint: None, None
size: '100dp', '30dp'
color: .8, 0, 0, 1
font_size: '16dp'
#pos_hint: {'center_x': 0.8, 'center_y': 0.5}
Label:
size_hint: 1, .035
text: ''
font_size: '1dp'
BoxLayout:
orientation: 'vertical'
padding: '10dp', 0
size_hint: 1, .38
FloatLayout:
TextInput:
id: new_post_input
#disabled: new_post.buttons_disabled
opacity: 1
background_color: 0, 0, 0, 1
foreground_color: 1, 1, 1, 1
background_disable_normal: True
multiline: True
font_size: '15dp'
padding: '10dp', '10dp'
selection_color: (.8, 0, 0, .5)
pos_hint: {'center_x': 0.5, 'center_y': 0.5}
allow_copy: True
#on_focus: new_post.on_focus(self)
canvas.after:
Color:
rgba: 1,1,1,1
Line:
width: dp(1.6)
rounded_rectangle:(self.x, self.y, self.width, self.height, dp(5))
BoxLayout:
orientation: 'vertical'
id: preview_new_post_label
opacity: 0
pos_hint: {'center_x': 0.5, 'center_y': -1}
canvas.before:
Color:
rgba: (.8,.8,.8,1)
RoundedRectangle:
size: self.size
radius: [dp(6),]
pos: self.x, self.y
canvas:
Color:
rgba:0.8,0,0,1
Line:
width: dp(1.6)
rounded_rectangle:(self.x,self.y,self.width,self.height, dp(5))
ScrollView:
always_overscroll: False
bar_color: (0,0,0,0)
Label:
text: ('Someone:\n' + new_post_input.text)
padding: "10dp", "12dp"
size_hint: None, None
height: self.texture_size[1]
width: self.parent.width
font_size: "12dp"
text_size: self.width, None
color: 0,0,0,1
multiline: True
markup: True
BoxLayout:
orientation: 'horizontal'
size_hint: 1, .08
padding: '10dp', 0
AnchorLayout:
anchor_x: 'left'
anchor_y: 'center'
Label:
text: 'Text Modification'
font_size: '12dp'
size_hint: None, None
BoxLayout:
orientation: 'vertical'
padding: '10dp', 0
size_hint: 1, .12
BoxLayout:
orientation: 'horizontal'
#padding: '10dp', 0
canvas.after:
Color:
rgba: 1, 1, 1, 1
Line:
width: 1.6
rounded_rectangle:(self.x, self.y, self.width, self.height, 5)
ScrollView:
GridLayout:
id: container_x
size_hint_x: None
rows: 1
col_default_width: dp(95)
width: self.minimum_width
spacing: dp(7)
Button:
text: "Bold"
font_size: '14dp'
color: 1, 1, 1, 1
background_color: .2, .2, .2, 0
on_press: new_post.make_bold(new_post_input, new_post_input.selection_text)
canvas.before:
Color:
rgba: (.2,.2,.2,0) if self.state=='normal' else (.3,.3,.3,1)
RoundedRectangle:
pos: self.pos
size: self.size
radius: [dp(6),]
canvas:
Color:
rgba: (1,1,1,1) if self.state=='normal' else (1,1,1,1)
Line:
width: dp(1.2)
rounded_rectangle:(self.x,self.y,self.width,self.height, dp(6))
BoxLayout:
orientation: 'horizontal'
size_hint: 1, .08
#padding: '10dp', 0
AnchorLayout:
anchor_x: 'left'
anchor_y: 'center'
Label:
text: 'Post Category'
font_size: '12dp'
size_hint: None, None
BoxLayout:
orientation: 'vertical'
padding: '10dp', 0
size_hint: 1, .12
BoxLayout:
orientation: 'horizontal'
#padding: '10dp', 0
canvas.after:
Color:
rgba: 1, 1, 1, 1
Line:
width: 1.6
rounded_rectangle:(self.x, self.y, self.width, self.height, 5)
ScrollView:
GridLayout:
id: container_x
size_hint_x: None
rows: 1
col_default_width: dp(95)
width: self.minimum_width
spacing: dp(7)
ToggleButton:
text: "Opinion"
font_size: '14dp'
color: 1, 1, 1, 1
background_color: .2, .2, .2, 0
on_press: new_post.update_catagory(self, 'opinions')
canvas.before:
Color:
rgba: (.2,.2,.2,0) if self.state=='normal' else (.3,.3,.3,1)
RoundedRectangle:
pos: self.pos
size: self.size
radius: [dp(6),]
canvas:
Color:
rgba: (1,1,1,1) if self.state=='normal' else (1,1,1,1)
Line:
width: dp(1.2)
rounded_rectangle:(self.x,self.y,self.width,self.height, dp(6))
Demo program working: YouTube link
Thank you for any suggestions/solutions :)
Update
It turns out that the selection seems to stop working when the TextInput is within a PageLayout with more than 2 pages in it, (Which it is in my program).
I have created a rough demo program to show the problem and have put it in .py and .kv
You can achieve that by creating a custom TextInput instance and overriding one of its method.
class MyTextInput(TextInput):
selected_text = StringProperty("")
# Use this prop. instead of 'selection_text'.
def cancel_selection(self):
self.selected_text = self.selection_text
super().cancel_selection()
Now use this instance and the new property wherever you need.
In .kv,
FloatLayout:
MyTextInput:
id: new_post_input
.
.
.
Button:
text: "Bold"
font_size: '14dp'
color: 1, 1, 1, 1
background_color: .2, .2, .2, 0
on_press: new_post.make_bold(new_post_input, new_post_input.selected_text)
Related
I tried to create a white popup window with rounded edges as the first image by using a canvas, but when I write canvas.after or canvas.before it comes behind or above the popup window content, so how I can make it looks like the first image?
.py file:
from kivy.app import App
from kivy.core.window import Window
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.uix.widget import Widget
from kivy.lang import Builder
from kivy.core.text import LabelBase
from kivy.uix.popup import Popup
Window.size = [300,600]
class MyLayout(Widget):
pass
class Exercise(App):
def build(self):
#Window color
Window.clearcolor = (249/255.0, 249/255.0, 249/255.0, 0)
Builder.load_file("myfile.kv")
#Loading .kv file
return MyLayout()
if __name__ == "__main__":
Exercise().run()
.kv file:
#: import Factory kivy.factory.Factory
<MyPopup#Popup>
auto_dismiss: False
title: ""
separator_height: 0
size_hint: 0.8, 0.4
background_color: (0,0,0,0)
background_normal: ''
canvas.before:
Color:
rgba:(255/255,255/255,255/255,1)
RoundedRectangle:
pos: self.pos
size: self.size
radius: [40]
BoxLayout:
orientation: "vertical"
size: root.width, root.height
padding: 0, 10, 10, 10
border: 50
border_color: (1,1,1,1)
Label:
text: "Good job"
color: 0,0,0,1
font_size: 16
CloseButton:
text: "Close"
color: 0,0,0,1
size_hint: (None , None)
width: 105
height: 40
pos_hint: {'center_x':0.5}
on_release: root.dismiss()
<MyLayout>:
BoxLayout:
orientation: "vertical"
size: root.width, root.height
padding: 20,40
#spacing: 20
Label:
font_size: 20
text: 'Click the button'
color: 0, 0, 0, 1
MyButton:
font_size: 20
text: "Button"
color: (0,0,0,1)
size_hint: (None , None)
width: 250
height: 50
pos_hint: {'center_x':0.5}
on_release: Factory.MyPopup().open()
<CloseButton#Button>:
background_color: (0,0,0,0)
background_normal: ''
canvas.before:
Color:
rgba:(252/255,131/255,87/255,1)
RoundedRectangle:
pos: self.pos
size: self.size
radius: [20]
<MyButton#Button>
background_color: (0,0,0,0)
background_normal: ''
canvas.before:
Color:
rgba:(252/255,131/255,87/255,1)
RoundedRectangle:
pos: self.pos
size: self.size
radius: [25]
Remove the canvas.before from the first part of the Popup and add it to the BoxLayout. Adjust the size and position of the canvas.before to make it cover the default background.
Here is the modified Popup definition that will work.
<MyPopup#Popup>
auto_dismiss: False
title: ""
separator_height: 0
size_hint: 0.8, 0.4
BoxLayout:
orientation: "vertical"
size: root.width, root.height
padding: 0, 10, 10, 10
border: 50
border_color: (1,1,1,1)
canvas.before:
Color:
rgba: 1, 1, 1, 1
RoundedRectangle:
pos: self.x - 20, self.y - 20
size: self.width + 40, self.height + 60
radius: [40]
Label:
text: "Good job"
color: 0,0,0,1
font_size: 16
CloseButton:
text: "Close"
color: 0,0,0,1
size_hint: (None , None)
width: 105
height: 40
pos_hint: {'center_x':0.5}
on_release: root.dismiss()
I'm trying to animate a dropdown symbol to rotate down (when the dropdown option is open) and revert back to it's original position (when dropdown option closes). Please find this attached screenshot.
Here's my py file:
from kivy.lang.builder import Builder
from kivymd.app import MDApp
from kivy.uix.screenmanager import Screen, ScreenManager
from kivy.utils import get_color_from_hex as hex
from kivy.animation import Animation
Builder.load_file("dropdowns_and_btns.kv")
kv = """
#:import hex kivy.utils.get_color_from_hex
#:import FadeTransition kivy.uix.screenmanager.FadeTransition
MyScreenManager:
transition: FadeTransition(duration=0)
IntroPage:
LandingPage:
ResultPage:
<IntroPage>
MDScreen:
md_bg_color: hex("#07074D")
MDLabel:
text: "BGF"
color: hex("#ECE4F5")
font_size: 36
pos_hint: {"center": (0.5, 0.7)}
halign: "center"
RoundedGradientButton:
text: "START"
font_size: 20
size_hint: 0.3, 0.08
pos_hint: {"center": (0.5, 0.3)}
on_release: app.root.current = "landing_page"
<LandingPage>
name: "landing_page"
MDScreen:
md_bg_color: hex("#07074D")
MDLabel:
icon_color: 1, 0, 1, 1
text: "Please select"
pos_hint: {"center_y": 0.9}
halign: "center"
font_size: 32
color: hex("#ECE4F5")
# Dropdown Label
MDFloatLayout:
size_hint: 0.75, 0.3
pos_hint: {"center": (0.5, 0.5)}
BoxLayout
size_hint: 0.5, 0.9
pos_hint: {"center": (0.26, 0.9)}
MDLabel:
text: "Month"
color: hex("#ECE4F5")
BoxLayout
size_hint: 0.5, 0.9
pos_hint: {"center": (0.79, 0.9)}
MDLabel:
text: "Year"
color: hex("#ECE4F5")
# Dropdown Button
MDGridLayout:
cols: 2
size_hint: 1, 0.3
pos_hint: {"center": (0.5, 0.65)}
spacing: 30
DropdownMenu:
id: month
text: 'Select'
values: [month for month, x in app.temp_db.items()]
on_text: self.text
DropdownMenu:
id: year
text: 'Select'
values: [f"{year}" for year in range(18, 46)]
on_text: self.text
# Find now button
RoundedGradientButton:
text: "FIND NOW"
font_size: 16
size_hint: 0.25, 0.25
pos_hint: {"center": (0.5, 0.15)}
<ResultPage>
name: "result_page"
MDScreen:
md_bg_color: hex("#07074D")
MDLabel:
id: result_prefix_label
text: "Congratulations!"
color: hex("#ECE4F5")
font_size: 20
pos_hint: {"center": (0.5, 0.7)}
halign: "center"
MDLabel:
id: result_label
color: hex("#ECE4F5")
font_size: 40
pos_hint: {"center": (0.5, 0.6)}
halign: "center"
Button:
background_normal: ""
background_color: 0, 0, 0, 0
pos_hint: {"center": (0.5, 0.3)}
on_press: app.root.current = "landing_page"
Image:
source: "images/reload.png"
center_x: self.parent.center_x
center_y: self.parent.center_y
size_hint_x: None
height: 50
"""
class IntroPage(Screen):
pass
class LandingPage(Screen):
pass
class ResultPage(Screen):
pass
class MyScreenManager(ScreenManager):
pass
class BabyGenderFinder(MDApp):
temp_db = {"January": 1, "February": 2, "March": 3, "April": 4, "May": 5}
def build(self):
return Builder.load_string(kv)
def DropdownBtnAnimation(self, wid):
ani = Animation(angle=-90, duration=0.02)
ani.start(wid)
BabyGenderFinder().run()
kv file:
#:import hex kivy.utils.get_color_from_hex
#:import Factory kivy.factory.Factory
# Drop down button setting
<DropdownMenu#Spinner>
dropdown_cls: Factory.CustomDropdown
option_cls: Factory.DropdownOptions
color: hex("#87828C")
font_name: "fonts/Poppins-Medium.ttf"
background_normal: ""
background_color: 0, 0, 0, 0
on_release: self.color = hex("ECE4F5") ; app.DropdownBtnAnimation(self.ids.dropdown_sign)
canvas.before:
Color:
rgba: hex("#111140")
RoundedRectangle:
size: self.size
pos: self.pos
radius: [6]
Color:
rgba: hex("#1F1F73")
Line:
width: 1.25
rounded_rectangle: self.x, self.y, self.width, self.height, 6, 6, 6, 6, 100
MDIconButton:
id: dropdown_sign
center_x: self.parent.center_x + 110
center_y: self.parent.center_y
angle: 0
canvas.before:
PushMatrix
Rotate:
angle: self.angle
axis: 0, 0, 1
origin: self.center
canvas.after:
PopMatrix
Image:
source: "images/dropdown.png"
size_hint: None, None
size: 20, 20
# Drop down options setting
<DropdownOptions#SpinnerOption>
color: hex("#ECE4F5")
font_name: "fonts/Poppins-Regular.ttf"
background_normal: ""
background_color: 0, 0, 0, 0
# Drop down options separator setting
canvas:
Color:
rgba: hex("#3D3D99")
Line:
width: 1
points: self.x+10, self.y, self.width-10, self.y
<CustomDropdown#DropDown>:
canvas.before:
Color:
rgba: hex("#1F1F73")
RoundedRectangle:
size: self.size
pos: self.pos
radius: [0, 0, 6, 6]
max_height: 200
# Gradient button settings
<RoundedGradientButton#Button>
background_normal: ""
background_color: 0,0,0,0
font_name: "fonts/Poppins-Medium.ttf"
on_press: self.size_hint = self.size_hint_x/1.05, self.size_hint_y/1.05
on_release: self.size_hint = self.size_hint_x*1.05, self.size_hint_y*1.05
canvas.before:
Color:
rgba: 1, 1, 1, 1
RoundedRectangle:
source: "button_bg.png"
size: self.size
pos: self.pos
radius: [self.size[1]/1.92]
I can make the button rotate down, but I can't seem to make the button go back to normal when dropdown options closes. I also want some actions done when I close Spinner widget (ex: If I clicked outside the dropdown options list when the list is open, I wanna trigger some actions)
I'm fairly new with kivy. Please help me.
In your kv, you can set the angle back to 0 when the text is changed on the DropdownMenu:
DropdownMenu:
id: month
text: 'Select'
values: [month for month, x in app.temp_db.items()]
on_text: self.ids.dropdown_sign.angle=0
Or, you can eliminate the animation completely, and just set the angle of the icon to depend on whether the DropdownMenu is open:
MDIconButton:
id: dropdown_sign
center_x: self.parent.center_x + 110
center_y: self.parent.center_y
# angle: 0
canvas.before:
PushMatrix
Rotate:
angle: 90 if root.is_open else 0 # adjusts angle of icon
axis: 0, 0, 1
origin: self.center
canvas.after:
PopMatrix
Image:
source: "images/dropdown.png"
size_hint: None, None
size: 20, 20
To create dropdown animation, we can create close animation method just like DropdownBtnAnimation in PY file:
class BabyGenderFinder(MDApp):
temp_db = {"January": 1, "February": 2, "March": 3, "April": 4, "May": 5}
def build(self):
return Builder.load_string(kv)
def DropdownBtnAnimation(self, wid):
ani = Animation(angle=-90, duration=0.02)
ani.start(wid)
def dropdown_btn_close_animation(wid):
ani = Animation(angle=0, duration=0.02)
ani.start(wid)
And use on_is_open property in kv:
<DropdownMenu#Spinner>
dropdown_cls: Factory.CustomDropdown
option_cls: Factory.DropdownOptions
color: hex("#87828C")
font_name: "fonts/Poppins-Medium.ttf"
background_normal: ""
background_color: 0, 0, 0, 0
on_is_open: app.DropdownBtnAnimation(self.ids.dropdown_sign) if self.is_open == True else app.dropdown_btn_close_animation(self.ids.dropdown_sign)
on_release: self.color = hex("ECE4F5")
canvas.before:
Color:
rgba: hex("#111140")
RoundedRectangle:
size: self.size
pos: self.pos
radius: [6]
Color:
rgba: hex("#1F1F73")
Line:
width: 1.25
rounded_rectangle: self.x, self.y, self.width, self.height, 6, 6, 6, 6, 100
Trying to color background of MDLabel (Label) in kivy app. But can not adjust width of the Label to be exactly the size of the text (content).
GridLayout:
cols: 1
BoxLayout:
orientation: 'vertical'
size_hint_y: None
padding: dp(7)
# pos_hint: {'top': 1}
background_color: (1,1,0,1)
height: self.minimum_height
canvas.before:
Color:
rgba: self.background_color
Rectangle:
size: self.size
pos: self.pos
BoxLayout:
size_hint_y: None
# pos_hint: {'top': 1}
height: self.minimum_height
background_color: (0,1,0,1)
canvas.before:
Color:
rgba: self.background_color
Rectangle:
size: self.size
pos: self.pos
MDLabel:
text: 'Some text'
size_hint_y: None
size: self.texture_size
MDLabel:
id: trying_to_color_background
text: 'Width'
halign: 'right'
size_hint_x: None
size: self.texture_size
getting this
enter image description here
if i try to remove last row of the code "size: self.texture_size". it looks like this
enter image description here
but i want the background to be the size of the text content (size of red border in the image below). if there will be more letters in the text, i want the background to be wider
enter image description here
Set it as,
...
MDLabel:
id: trying_to_color_background
text: 'Width'
halign: 'right'
size_hint: None, None
size: self.texture_size
text_size: None, None
lbl_state = MDLabel(text="state", md_bg_color = [.119, .136, .153, 1])
lbl_state = MDLabel(text="state", theme_text_color = "Custom", md_bg_color = [.119, .136, .153, 1])
from kivy.utils import get_color_from_hex
lbl_state = MDLabel(text="state", theme_text_color = "Custom", md_bg_color = get_color_from_hex("#7dcbb1"))
MDLabel:
id: trying_to_color_background
theme_text_color: "Custom"
md_bg_color = .119, .136, .153, 1
Example for different colors:
0, 0, 0, 1 - dark
1, 1, 1, 1 - white
.7, .7, .7, 1 - gray
1, 0, 0, 1 - red
0, 1, 0, 1 - green
0, 0, 1, 1 - blue
In my program I have a button that adds a new box. When you press a button in this new box it adds a new box, and so on. In each box I have a label, and I want to be able to change this text from the same textinput field. But I dont want the same text in each box, so I want to select the box, write the text, and then press a button so that the text is passed from the input field to that specific box/label. I have removed everything else from my app, so I will show you a complete code so you can try the program to understand what I mean.
I have tried to use a button on the main widget, but then I dont know how to choose which box that should be updated. I have also tried to use a button in the box (called "R" in the code), but then I only gets an error.
If i use the code that is commented out i get this error:
"AttributeError: 'super' object has no attribute '__getattr__'"
I would really appreciate some help! Thanks a lot.
This is the python file:
from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
class Home(FloatLayout):
def first(self, *args):
a = box()
self.ids.frame.add_widget(a)
b = a.ids.btn3
b.bind(on_press=self.second)
c = a.ids.btn1
c.bind(on_press=self.textedit)
def second(self, *args):
d = box()
e = d.ids.mains
e.pos_hint={"right": .5, "top": .7}
self.ids.frame.add_widget(d)
f = d.ids.btn3
f.bind(on_press=self.third)
g = d.ids.btn1
g.bind(on_press=self.textedit)
def third(self, *args):
h = box()
i = h.ids.mains
i.pos_hint = {"right": .3, "top": .9}
self.ids.frame.add_widget(h)
j = h.ids.btn1
j.bind(on_press=self.textedit)
def textedit(self, *args):
print("Hello")
#k = self.ids.tinput.text
#l = self.ids.lab
#l.text = k
def textedit2(self, *args):
print("hei")
#This is the submitbutton on the main widget
class HiApp(App):
def build(self):
return Home()
class box(FloatLayout):
pass
if __name__ == "__main__":
HiApp().run()
This is the .kv file
<Home>:
FloatLayout:
id: frame
size_hint_y: 1
pos_hint:{"right":1,"top":1}
canvas.before:
Color:
rgba: (1, 1, 1, 1)
Rectangle:
size: self.size
pos: self.pos
BoxLayout:
id: boks
orientation: "vertical"
size_hint_x: .20
size_hint_y: .15
pos_hint:{"right":1,"top":1}
canvas.before:
Color:
rgba: (0, 1, 0, 1)
Rectangle:
size: self.size
pos: self.pos
TextInput:
id: tinput
hint_text: "Frome here"
Button:
id: t_sub
text: "Submit"
on_press: root.textedit2()
Button:
id: start
text: "Start"
font_size: 20
color: 0, 0, 0, 1
background_normal: ''
background_color: .88, .88, .88, 1
size_hint: .1, .1
pos_hint:{"right":.5,"top":.35}
on_press: root.first()
<box>:
BoxLayout:
id: mains
orientation: "vertical"
size_hint_x: .18
size_hint_y: .13
pos_hint:{"right":.3,"top":.5}
canvas.before:
Color:
rgba: (.20, .05, .0, 1)
Rectangle:
size: self.size
pos: self.pos
BoxLayout:
id: c1
size_hint_y: .25
pos_hint:{"left":.1,"top":.5}
GridLayout:
rows: 1
cols: 3
padding: 4
spacing: 4
Button:
id: btn1
text: "R"
font_size: 30
color: 0, 0, 0, 1
background_normal: ''
background_color: .88, .88, .88, 1
size_hint: .3, .3
pos_hint:{"left":.5,"top":.5}
on_press:
Button:
id: btn2
text: "-"
font_size: 30
color: 1, 0, 0, 1
background_normal: ''
background_color: .88, .88, .88, 1
size_hint: .3, .3
pos_hint:{"left":.5,"top":.5}
on_press:
Button:
id: btn3
text: "+"
font_size: 30
color: 0, 1, 0, 1
background_normal: ''
background_color: .88, .88, .88, 1
size_hint: .3, .3
pos_hint:{"left":.5,"top":.5}
on_press:
GridLayout:
rows: 1
cols: 2
padding: 4
spacing: 4
Label:
id: lab
text: "Text here"
TextInput:
hint_text: "0"
Problem
I want to write the text in the inputfield with the id: tinput
(upper left corner) and then press the button (R) so that the text
goes from the inputfield to the label.
Solution
The solution to is use the following keywords in kv file:
app - always refers to the instance of your application
root - refers to the base widget/template in the current rule
Snippets - kv file
Button:
id: btn1
text: "R"
font_size: 30
color: 0, 0, 0, 1
background_normal: ''
background_color: .88, .88, .88, 1
size_hint: .3, .3
pos_hint:{"left":.5,"top":.5}
on_press:
lab.text = app.root.ids.tinput.text
Output
When i pass blank value in array
arr = ({'Item1': ''},{'Item2': 1000})
then it show 0 instead of blank value.
1. Can someone tell me how to set blank by deafault instead of 0 ?
2. How to make key(Item1) bold?
main.py
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import Screen
def convert_data(data):
l = []
for item in data:
for key, value in item.items():
l.append({'text': key, 'value': value})
return l
class Invoice(Screen):
def abc(self):
#fetching from database
arr = ({'Item1': ''},{'Item2': 1000})
# convert to [{'text': 'Item1', 'value': 5000}, {'text': 'Item2', 'value': 1000}]
self.rv.data = convert_data(arr)
class MyApp(App):
def build(self):
return Builder.load_file('test.kv')
if __name__ == '__main__':
MyApp().run()
test.kv
<Button#Button>:
font_size: 15
size_hint_y:None
height: 30
<Label#Label>:
font_size: 15
size_hint_y:None
height: 30
<Item#GridLayout>:
cols: 2
text: ""
value: 0
padding : 5, 0
spacing: 10, 0
Label:
size_hint_x: .35
text: root.text
halign: 'left'
valign: 'middle'
canvas.before:
Color:
rgb: .6, .6, .6
Rectangle:
pos: self.pos
size: self.size
Label:
size_hint_x: .15
text: str(root.value)
halign: 'right'
valign: 'middle'
canvas.before:
Color:
rgb: .6, .6, .6
Rectangle:
pos: self.pos
size: self.size
Invoice:
rv: rv
BoxLayout:
orientation: "vertical"
padding : 15, 15
BoxLayout:
orientation: "vertical"
padding : 5, 5
size_hint: .6, None
pos_hint: {'x': .18,}
BoxLayout:
orientation: "horizontal"
padding : 5, 5
spacing: 10, 10
size: 800, 40
size_hint: 1, None
Button:
text: "Show"
size_hint_x: .05
spacing_x: 30
on_press:root.abc()
BoxLayout:
orientation: "horizontal"
size_hint: 1, 1
BoxLayout:
orientation: "vertical"
size_hint: .5, 1
padding : 0, 15
spacing: 10, 10
size: 500, 30
Button:
text: "Invoice"
text_size: self.size
halign: 'center'
valign: 'middle'
BoxLayout:
RecycleView:
id: rv
viewclass: 'Item'
RecycleBoxLayout:
default_size: None, dp(30)
default_size_hint: 1, None
size_hint_y: None
height: self.minimum_height
orientation: 'vertical'
When I proposed this code in a previous question I assumed that the second fields were always going to be integers and not string, so create the value: 0 property which, as seen, accepts only numerical values since it is mapped as NumericProperty. The solution is to convert it to StringProperty by changing to value:"" besides changing the line of convert_data so that it does the conversion of integers to string.
In the second case to be able to use bold in the text we must set markup to True in Label and use [b] [/b] before and after the text that we want to modify.
All of the above implies the following changes:
*.py
[...]
def convert_data(data):
l = []
for item in data:
for key, value in item.items():
l.append({'text': key, 'value': str(value)}) # change this line
return l
[...]
*.kv
[...]
<Item#GridLayout>:
cols: 2
text: ""
value: ""
padding : 5, 0
spacing: 10, 0
Label:
size_hint_x: .35
text: "[b]{}[/b]".format(root.text)
markup: True
halign: 'left'
valign: 'middle'
canvas.before:
Color:
rgb: .6, .6, .6
Rectangle:
pos: self.pos
size: self.size
Label:
size_hint_x: .15
text: root.value
halign: 'right'
valign: 'middle'
canvas.before:
Color:
rgb: .6, .6, .6
Rectangle:
pos: self.pos
size: self.size
[...]