Kivy TextInput Text Overflow. Cursor Outside TextInput Viewport - kivy

The last letter is overflowing
I'm using Kivy 1.10.1. I've added a text input (multiline = False). The sentence entered above is "This is a long sentence being typed into Kivy". All the letters have been entered. But the last letter - the "y" is outside the text input.
I've tried changing the padding size, the border size and changing the size of the textinput itself. I don't know if I'm doing something wrong or it is a bug with the library.
Edit:( I should have added the widget code here )
text_input: input_text_field
canvas:
Color:
rgba: self.background_color_intensity_red, self.background_color_intensity_green, self.background_color_intensity_blue, 1
Rectangle:
size: 396, 768
pos: self.pos
source: "sprites/phone.png"
BoxLayout:
size: 354, 598
pos: 21, 96
orientation: 'vertical'
BoxLayout:
size_hint: 1, 0.1
pos: root.pos
orientation: 'horizontal'
Image:
size_hint: 0.15, 1
source: "sprites/profile_pic.png"
TextInput:
id: input_text_field
size_hint: 0.85, 0.5
pos_hint: {'top': 0.75}
background_color: 1,1,1,1
border: (20, 20, 20, 20)
multiline: False
halign: 'center'
focus: True
on_text_validate: self.parent.parent.parent.on_text_input()
BoxLayout:
size_hint: 1, 0.9
pos: root.pos
orientation: 'vertical'
Thank you.

Related

Popup fails depending on what I BIND

Here is the relevant portion of my Animal Picker in KIVY file shown below:
AniPic#ANIMALPICKER
id: aroot
labelText: ''
imageSource: ''
animalCode: 'AB'
animalName: 'GOGGA'
BoxLayout:
orientation: 'horizontal'
width: root.width
pos: 0,0
canvas.before:
RoundedRectangle:
pos: 5, 5
# the next two lines determine the position of the rectangle for the image
size: root.width-10, root.height-10
source: root.imageSource
radius:[10]
PinButton:
id: _pin
on_release:
root.pin_action(root.labelText)
Label:
id: _label
text: root.labelText
width: root.width
color: (1, 1, 1, 1)
MapButton:
id: _map
on_release:
root.map_show(root.labelText)
#==========================================================================
AnimalWindow:
:
id: animalid
name: 'animal'
canvas.before:
Color:
rgba: 1, 1, 1, 1
Rectangle:
pos: self.pos
size: self.size
BoxLayout:
orientation: 'vertical'
Label:
id: choice
text: "Sightings"
color: 0, 0, 0, 1
size_hint_y: 0.05
canvas.before:
Color:
rgba: 0.5, 1, 0.5, 1
Rectangle:
pos: self.pos
size: self.size
ScrollView:
do_scroll_x: False
do_scroll_y: True
GridLayout:
size: (root.width, root.height)
cols: 1
rows: 9
padding: 10
spacing: 10
size_hint_x: None
size_hint_y: 9
height: self.minimum_height
row_default_height: 120
row_force_default: True
AniPic:
labelText: 'LION'
imageSource: 'images/lion_pic.jpg'
animalCode: 'LI'
AniPic:
labelText: 'CHEETAH'
imageSource: 'images/cheetah_pic.png'
animalCode: 'CH'
Now when I click on a 'PinButton' of a particular animal (CHEETA) I get the app executing
def pin_it(_animal):
print('aaaa', _animal )
and shows.
'aaaa CHEETAH'
BUT the POPUP code below, where I want 'confirmation' for pin action, does not show the popup but crashes:
class ANIMALPICKER(RelativeLayout):
def pin_action(self, _animal):
# Prepare to confirm that you want to Pin the sighting
title_text = _animal + ' ' + 'SIGHTING'
content_text = 'Confirm Sighting?'
content_box = BoxLayout(orientation='vertical')
btn_box = BoxLayout(orientation='horizontal')
btn_box.height = 24
content_label = Label()
content_label.text = content_text
yes_btn = Button(text='Yes')
yes_btn.background_color = 0, 1, 0, 1
no_btn = Button(text='No')
no_btn.background_color = 1, 0, 0, 1
btn_box.add_widget(yes_btn)
btn_box.add_widget(no_btn)
content_box.add_widget(content_label)
content_box.add_widget(btn_box)
# Now confirm that you want to Pin the sighting
popup = Popup(title=title_text,
separator_height=4,
title_size='20sp',
content=content_box,
size_hint=(None, None),
size=(200, 240),
auto_dismiss=False)
# dismiss popup and proceed to pin the sighting, on release of yes button
yes_btn.bind(on_press=pin_it(_animal))
# dismiss popup on release of the NO button
yes_btn.bind(on_release=popup.dismiss)
popup.open()
with the following message:
File "/home/sib/PycharmProjects/SpotMap/animalWindow.py", line 66, in pin_action
yes_btn.bind(on_press=pin_it(_animal))
File "kivy/_event.pyx", line 444, in kivy._event.EventDispatcher.bind
AssertionError: None is not callable
However when I bind a simple 'yes_btn.bind(on_press=dismiss)' instead of 'yes_btn.bind(on_press=pin_it(_animal))' the popup does display and the the popup dismisses when the button to which it is attached is pressed.
Please at 82 years of age and a limited knowledge of Python, Kivy and OO I desperately need help in completing this app.
A work around will also satisfy me
Many Thanks
I think the problem is that pin_it(_animal) completes the function instead of referencing the function object.
from functools import partial
myfun = partial(pin_it, animal=_animal)
# this should be a function, not function()
yes_btn.bind(on_press=myfun)

Kivy. Checkbox on top of background image

My goal is to set the checkbox on top of the image in below class. I'm struggling to find a layout in which I can position one layout above another. The only way I could think of at the moment is to show the image as the background image of RelativeLayout not as AsyncImage but I believe there is a clean way to achieve this.
Class
<FriendTile>
orientation: 'vertical'
size_hint: None, None
height: pic.height + username.height
width: pic.width
background_color: app.alert_color
active_color: app.main_bcolor
unactive_color: app.main_bcolor
canvas.before:
Color:
rgba: (0, 0, 1, 1) if self.background_color is None else self.background_color
Rectangle:
pos: self.pos
size: self.size
RelativeLayout:
id: pic
size_hint: None, None
size: 100, 100
CheckBox:
size_hint: .1, .1
pos_hint: {'top': 1, 'right': 1}
canvas.after:
Color:
rgba: (0, 1, 0, 1)
Rectangle:
pos: self.pos
size: self.size
AsyncImage:
id: image
size_hint: .9, .9
pos_hint: {'center_x': .5, 'center_y': .5}
source: root.avatar
canvas.before:
Color:
rgba: (0, 1, 1, 1) # if root.background_color is None else root.background_color
Rectangle:
pos: self.pos
size: self.size
Expectations
Reality

Move search items more to the top

I have the following code snippet displaying a popup Window.
class SearchBar(TextInput):
articles = ListProperty()
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.bind(text=self.on_text)
self.bind(articles=self.on_articles)
def on_text(self, *args):
WikiSearcher().get_search_results(self.text, self)
def on_articles(self, *args):
self.parent.parent.children[0].update_recommendations(self.articles)
class SearchItem(ButtonBehavior, Label):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.url = ''
def on_release(self):
print (self.url)
class Recommendations(BoxLayout):
def update_recommendations(self, recommendations: list):
for (search_item, recommendation) in zip(reversed(self.children), recommendations):
search_item.text = recommendation
try:
search_item.url = wikipedia.page(recommendation).url
except:
search_item.url = 'https://en.wikipedia.org/wiki/' + recommendation.replace(" ", "_")
Builder.load_string('''
<SearchItem>:
font_size: self.height * 0.4
canvas.before:
Color:
rgba: [0.8, 0.8, 0.8, 1] if self.state == 'normal' else [30/255, 139/255, 195/255, 1]
Rectangle:
#pos: self.pos
#size: self.size[0], self.size[1]
size: root.size[0], root.size[1]
pos: self.pos[0], self.pos[1]
Color:
rgba: 0, 0, 0, 1
Line:
rectangle: self.x, self.y, self.width, self.height
color: 0, 0, 0, 1
<Urlpup>:
size_hint: 1, 1
auto_dismiss: False
title: 'Enter URL or keywords'
BoxLayout:
canvas.before:
Color:
rgba: 1, 1, 1, 1
Rectangle:
size: self.size
pos: self.pos
orientation: 'vertical'
padding: self.width * 0.1
spacing: self.height * 0.1
BoxLayout:
orientation: 'horizontal'
Spinner:
id: spinner
size_hint: 0.5, 0.4
pos_hint: { 'top' : 1 }
text: 'en'
values: 'en', 'fr', 'de', 'it'
SearchBar:
id: url_input
size_hint: 1, 0.4
pos_hint: { 'center_x' : 0.5, 'top' : 1 }
multiline: False
font_size: self.height*0.8
Button:
text: 'OK'
size_hint: 0.5, 0.4
pos_hint: { 'top' : 1 }
on_press: root.dismiss()
on_release: app.create_new_article(url_input.text)
Recommendations:
id: recommendations
orientation: 'vertical'
SearchItem
SearchItem
SearchItem
SearchItem
''')
class Urlpup(Popup):
pass
Here is a picture of the popup Window
You can see that the SearchItems are not tightly below the SearchBar, where I'm struggling to position it. Can you fix it? On the picture there are 4 SearchItems but I plan to have 10 Searchitems so it should work for 10 SearchItems or be flexible when I decide to change the number of SearchItems
The BoxLayout tries to distribute its available space equally among its children, unless you tell it otherwise. So, your top level BoxLayout in the Urlpup class evenly divides its space between the BoxLayout containing the TextInput and the Recommendations widget. You can reduce the space between those two widgets by limiting the space given to the horizontal BoxLayout. You can do that by specifying a height for that BoxLayout, like this:
BoxLayout:
size_hint_y: None
height: 50
orientation: 'horizontal'
Spinner:
id: spinner
size_hint: 0.5, 1
pos_hint: { 'top' : 1 }
text: 'en'
values: 'en', 'fr', 'de', 'it'
SearchBar:
id: url_input
size_hint: 1, 1
pos_hint: { 'center_x' : 0.5, 'top' : 1 }
multiline: False
font_size: self.height*0.8
Button:
text: 'OK'
size_hint: 0.5, 1
pos_hint: { 'top' : 1 }
on_press: root.dismiss()
on_release: app.create_new_article(url_input.text)
Note that the children of this BoxLayout all have a size_hint_y of 1.0, so they will all be the height that is specified for their container.
The Recommendations widget gets the remaining vertical space (minus the spacing). You can move the Recommendations even closer by reducing the spacing.

How can I make border to the text in the label?

I'm still learning kivy language .
please can you tell me how to add a border to a text in a label in the kv file
and thanks
In the kivy language documentation, you can redefine a widget's style by adding a - to the beginning of the kv rule. So, in the kv you can define a new widget like this:
<-LabelWithBorder#Label>:
border_width: 0
border_color: [1,1,1,1]
canvas.before: # draw the border
Color:
rgba: root.border_color if root.border_width > 0 else [0,0,0,1]
Rectangle:
size: self.size
pos: self.pos
Color:
rgba: 0, 0, 0, 1
Rectangle:
size: self.width - 2*root.border_width, self.height - 2*root.border_width
pos: int(self.center_x - (self.width - 2*root.border_width)/2.), int(self.center_y - (self.height - 2*root.border_width)/2.)
canvas: # modified from Label
Color:
rgba: 1, 1, 1, 1
Rectangle:
texture: self.texture
size: self.texture_size[0] - 2*root.border_width, self.texture_size[1] - 2*root.border_width
pos: int(self.center_x - self.width/2.) + root.border_width, int(self.center_y - self.height/2.) + root.border_width
The canvas.before is the section that draws the border, and the canvas section is the normal Label style with slight modifications to account for the border.
This can be used, for example, like this:
FloatLayout:
LabelWithBorder:
text: 'Hello, World'
font_size: 50
border_width: 10
border_color: [1,0,0,1]
size_hint: None, None
size: self.texture_size
pos_hint: {'center_x':0.5, 'center_y':0.5}
I believe you are looking for 'outline'
This is the docs link for it Label Outline - Kivy Docs
Here's some example code (color defaults to black .. 0, 0, 0, 1):
Label:
id: label_StackOverflowSample
pos_hint: {"x": 0.25, "y": 0.18}
size_hint: 0.6, 0.365
font_size: 18
text_size: self.size
halign: 'left'
italic: True
outline_width: 10
outline_colour: (0, 0, 0, 1)
text:
'''
long long long
long long long
long long long
long long long
long long long
textt
'''
And this is a picture showing its example:
sorry, not enough reputation to post pictures yet
Hope this helps

Kivy: TextInput border radius

I would like to know if it was possible in python & Kivy, to customize TextInput widgets like in HTML/CSS. Is there any way to do that directly into my CustomTextInput(TextInput) class ?
I want my TextInput looks like this:
Of course you can, but it's a bit more complicated in kivy:
test.kv:
#:import C kivy.utils.get_color_from_hex
<MyTextInput#TextInput>:
font_size: '14dp'
background_color: 0,0,0,0
cursor_color: C('#ffffff')
canvas.before:
Color:
rgba: C('#ffffff')
canvas.after:
Color:
rgb: C('#0f192e')
Ellipse:
angle_start:180
angle_end:360
pos:(self.pos[0] - self.size[1]/2.0, self.pos[1])
size: (self.size[1], self.size[1])
Ellipse:
angle_start:360
angle_end:540
pos: (self.size[0] + self.pos[0] - self.size[1]/2.0, self.pos[1])
size: (self.size[1], self.size[1])
Color:
rgba: C('#3f92db')
Line:
points: self.pos[0] , self.pos[1], self.pos[0] + self.size[0], self.pos[1]
Line:
points: self.pos[0], self.pos[1] + self.size[1], self.pos[0] + self.size[0], self.pos[1] + self.size[1]
Line:
ellipse: self.pos[0] - self.size[1]/2.0, self.pos[1], self.size[1], self.size[1], 180, 360
Line:
ellipse: self.size[0] + self.pos[0] - self.size[1]/2.0, self.pos[1], self.size[1], self.size[1], 360, 540
BoxLayout:
orientation:'vertical'
BoxLayout:
size_hint_y: 20
canvas.before:
Color:
rgba: C('#3f92db')
Rectangle:
pos:self.pos
size:self.size
BoxLayout:
orientation: 'vertical'
size_hint_y: 80
canvas:
Color:
rgba: C('#18294a')
Rectangle:
pos:self.pos
size:self.size
BoxLayout:
size_hint_y: 10
BoxLayout:
size_hint_y: 20
orientation:'vertical'
Label:
size_hint_y: 8
text: 'Password'
color: C('#ffffff')
font_size:'20dp'
padding: 5,5
text_size: self.size
halign: 'center'
valign: 'center'
BoxLayout:
size_hint_y: 8
BoxLayout:
size_hint_x: 25
BoxLayout:
size_hint_x: 50
canvas.before:
Color:
rgba: C('#0f192e')
Rectangle:
pos: self.pos
size: self.size
MyTextInput:
BoxLayout:
size_hint_x: 25
BoxLayout:
size_hint_y: 10
BoxLayout:
size_hint_y: 20
orientation:'vertical'
Label:
size_hint_y: 8
text: 'Confirm'
color: C('#ffffff')
font_size:'20dp'
padding: 5,5
text_size: self.size
halign: 'center'
valign: 'center'
BoxLayout:
size_hint_y: 8
BoxLayout:
size_hint_x: 25
BoxLayout:
size_hint_x: 50
canvas.before:
Color:
rgba: C('#0f192e')
Rectangle:
pos: self.pos
size: self.size
MyTextInput:
BoxLayout:
size_hint_x: 25
BoxLayout:
size_hint_y: 40
python file:
from kivy.app import App
class TestApp(App):
pass
if __name__ == '__main__':
TestApp().run()
output:

Resources