Adjust Kivy FileChooser Font Size - python

I'm looking for how I can change the font size of all text in a kivy FileChooserListView class. I am hoping to do so in pure python if possible. I like that the standard Label and Button uix classes take font_size as an initialize parameter, but it appears the FileChooserListView does not. If doing so in pure python isn't an easy approach and there's a good .kv file approach, I'd take that too. Thanks!

There is no direct way to do that, but you can fiddle with the FileListEntry template that the FileChooserListView uses to display the entries. In that template, you can adjust the font sizes used. Here is my attempt at that:
Builder.load_string('''
[FileListEntry#FloatLayout+TreeViewNode]:
locked: False
entries: []
path: ctx.path
# FIXME: is_selected is actually a read_only treeview property. In this
# case, however, we're doing this because treeview only has single-selection
# hardcoded in it. The fix to this would be to update treeview to allow
# multiple selection.
is_selected: self.path in ctx.controller().selection
orientation: 'horizontal'
size_hint_y: None
height: '96dp' if dp(1) > 1 else '48dp' # height must be big enough to hold font sized below
# Don't allow expansion of the ../ node
is_leaf: not ctx.isdir or ctx.name.endswith('..' + ctx.sep) or self.locked
on_touch_down: self.collide_point(*args[1].pos) and ctx.controller().entry_touched(self, args[1])
on_touch_up: self.collide_point(*args[1].pos) and ctx.controller().entry_released(self, args[1])
BoxLayout:
pos: root.pos
size_hint_x: None
width: root.width - dp(10)
Label:
id: filename
font_size: '48dp' # adjust this font size
size_hint_x: None
width: root.width - sz.width # this allows filename Label to fill width less size Label
text_size: self.width, None
halign: 'left'
shorten: True
text: ctx.name
Label:
id: sz
font_size: '48dp' # adjust this font size
#text_size: self.width, None
size_hint_x: None
width: self.texture_size[0] # this makes the size Label to minimum width
text: '{}'.format(ctx.get_nice_size())
''')
This is based heavily on the FileListEntry template in style.kv. There are two font_sizes that you can adjust, and a height for the entry. All three must be coordinated to get a reasonable result.

Related

Multiple valigns in one label

I am programming a Chat Bot and I want to build a GUI using kivy. To make the chat I am using labels in a scrollview:
GridLayout:
cols: 1
rows: 0
ScrollView:
size: self.size
do_scroll_x: False
Label:
id: msg
text_size: self.width,None
size_hint_y: None
height: self.texture_size[1]
font_size: 20
Python Code:
def send(self,x):
#global msgback
self.msg_list.text += str(x + "\n")
The problem is, that I do not know how to make the valign, that only makes the messages from the user on the right side. How do I do that?
Use halign to align text to the right.
Label:
id: msg
text_size: self.width,None
size_hint_y: None
height: self.texture_size[1]
font_size: 20
halign: 'right'
valign: 'middle'
Label » halign
halign
Horizontal alignment of the text.
halign is an OptionProperty and defaults to ‘left’. Available options
are : left, center, right and justify.
Warning
This doesn’t change the position of the text texture of the Label
(centered), only the position of the text in this texture. You
probably want to bind the size of the Label to the texture_size or set
a text_size.

How to use pos_hint with FloatLayout in kivy?

I am trying to align labels and button in my test UI this is my kv file
<test>:
Label:
text: "foo"
color: 0,1,0,1
#pos:120,20
pos_hint:{"right":0.1,"top":1}
Label:
text:"boo"
color: 0,0,1,1
#pos:80,20
pos_hint:{"right":0.1,"top":0.5}
Label:
text:"bar"
color: 1,0,0,1
#pos:20,120
pos_hint:{"right":0.1,"top":0.1}
Button:
text:"goo"
size_hint:0.1,0.1
I am able to succesfully create labels foo,boo and bar using pos but when I used pos_hint it returns blank output?
You are getting "blank" output because the text of the labels is off screen (and the labels themselves are transparent).
Since your layout <test> has no size_hint so it takes on the
default of (1,1) which makes it the size of the Window (which is
800 x 600).
Your labels also don't have a size_hint so they default to the size of their parent - the layout, so they end up having size [800, 600]. The text in the labels is centered by default, and their background is transparent. (maybe you should try this with buttons first so you have a visual representation of the sizes)
Thus, the text a label with pos = (0,0) will appear in the center of the screen
Then we have the pos_hint taking different arguments (the below description might not be accurate for things outside of a FloatLayout):
pos_hint:{"right":v1,"top":v2} sets the pos to (self.parent.right*v1 - self.width, self.parent.top*v2 - self.height) - you are setting the top and right of the widget you are placing. Thus your labels get such negative coordinates that their texts never appear on screen (because bottom left is 0,0)
then we have pos_hint:{"x":v1,"y":v2} (which you may find more useful for your case), and pos_hint:{"center_x":v1,"center_y":v2}. You should be able to figure out how they work bearing in mind that the size affects how things looks, since pos only sets the bottom left coordinate.. you can play around with this .kv file:
#:kivy 1.0.9
<test>:
#size: (500, 500)
#size_hint:(None, None)
canvas:
Color:
rgb: 1,0,0
Rectangle:
size: (5,5)
pos: (0,0)
Widget:
id:wig
pos: (250,250)
canvas:
Color:
rgb: 1,1,1
Rectangle:
size: (5,5)
pos: self.pos
Label:
id: boo
text:"boo"
color: 0,0,1,1
#size_hint:(1,1)
pos_hint:{"center_x":1,"center_y":1}
Label:
id: foo
text: "foo"
color: 0,1,0,1
#size_hint: (.6,.6)
pos_hint:{"x":1,"y":1}
Label:
id: bar
text:"bar"
color: 1,0,0,1
#size:(500,500)
#size_hint:(None, None)
pos_hint:{"right":1,"top":1}
#pos:100, 10
Button:
text:"goo"
size_hint:0.1,0.1
pos:(1,1)
#some debug info, i know the code is ugly
on_press: print self.parent.size,'\n', self.parent.right, self.parent.top, self.parent.x, self.parent.y, self.parent.center_x, self.parent.center_y, "\n","bar_right_top:", bar.pos,"foo_x_y:", foo.pos,"boo_center:", boo.pos, "\nwhite square:", wig.pos, "\n", bar.size, foo.size, boo.size

GridLayout Not Scrolling in Kivy

Please tell me why this doesn't work, the whole program works fine, it uses a function inside the main program to get it's text, but it won't scroll so the user won't be able to view the entire output.
<AnswerScreen#Screen>:
input_textb: input_textb
ScrollView:
size_hint: (1, None)
do_scroll_y: True
do_scroll_x: False
bar_width: 4
GridLayout:
padding: root.width * 0.02, root.height * 0.02
cols: 1
size_hint_y: None
size_hint_x: 1
height: self.minimum_height
Label:
id: input_textb
text: ""
font_size: root.height / 25
text_size: self.width, None
Edit:
I had already tried doing the same as many previous answers, in the particular one mentioned in the comments, I got an error saying "NoneType" has no attribute "bind".
I removed the size hint, it still doesn't work, but thanks anyway.
The text is definitely long enough.
I believe the label's size is not set, which i agree can be confusing at first, Label has a widget size (size as all widgets) and a texture_size, which is set to the actual size of the displayed text, kivy doesn't relate these two in any particular way at first, and it's up to you to decide how one influences the other, you did half of the work in setting text_size to (width, None), which forces the texture into having the width of the widget, but you are missing the other part of the deal, which is that you want to be the widget to be as tall as the generated texture. For this size to be effective, you also have to disable size_hint_y for Label, since it's in a GridLayout.
Label:
id: input_textb
text: ""
font_size: root.height / 25
text_size: self.width, None
height: self.texture_size[1]
size_hint_y: None
and you should be all set.
You should set a value for the property scroll_y of the ScrollView between 0 and 1.

Kivy (kv language) StackLayout Issue and Boundary Issue

I'm new to Kivy and still working out the best way to use it. Currently, I'm taking an example from their repo (textsize demo) and attempting to use layout concepts in a personal project.
At the end of the day, all I want is a "navbar" at the top of my screen and a content section below it. At the moment, I'm trying to accomplish this with a BoxLayout which includes a StackLayout (nav items) and a GridLayout (other content).
My Code Snippet:
<WindowWidget>:
BoxLayout:
orientation: 'vertical'
StackLayout:
Label:
text: 'Test1'
Label:
text: 'Test1.1'
Label:
text: 'Test2'
This code produces this: Kivy Screenshot.
I don't understand why label 1.1 is pushed down on top of label 2 rather than appearing beside label 1.
I added the following code taken from the kivy examples hoping the height setting would add some clarity, but I get the error below:
Code:
<StackLayout>:
size_hint_y: None
spacing: dp(6)
padding: dp(6), dp(4)
height: self.minimum_height
Error:
Warning, too much iteration done before the next frame. Check your
code, or increase the Clock.max_iteration attribute
This is caused by my inclusion of the "height: self.minimum_height" line. However, this works in the demo, so I'm not sure how I managed to screw it up. I'll include the example's kv code below for reference.
The original:
BoxLayout:
orientation: 'vertical'
HeadingLabel:
text: 'These modify all demonstration Labels'
StackLayout:
# Button is a subclass of Label and can be sized to text in the same way
Button:
text: 'Reset'
on_press: app.reset_words()
ToggleButton:
text: 'Shorten'
on_state:
app.shorten=self.state=='down'
ToggleButton:
text: 'max_lines=3'
on_state:
app.max_lines=3 if self.state=='down' else 0
Spinner:
text: 'bottom'
values: 'bottom', 'middle', 'top'
on_text: app.valign=self.text
Spinner:
text: 'left'
values: 'left', 'center', 'right', 'justify'
on_text: app.halign=self.text
GridLayout:
id: grid_layout
cols: 2
height: cm(6)
size_hint_y: None
HeadingLabel:
text: "Default, no text_size set"
HeadingLabel:
text: 'text_size bound to size'
DemoLabel:
id: left_content
disabled_color: 0, 0, 0, 0
DemoLabel:
id: right_content
text_size: self.size
padding: dp(6), dp(6)
ToggleButton:
text: 'Disable left'
on_state:
left_content.disabled=self.state=='down'
# Need one Widget without size_hint_y: None, so that BoxLayout fills
# available space.
HeadingLabel:
text: 'text_size width set, size bound to texture_size'
text_size: self.size
size_hint_y: 1
DemoLabel:
id: bottom_content
# This Label wraps and expands its height to fit the text because
# only text_size width is set and the Label size binds to texture_size.
text_size: self.width, None
size: self.texture_size
padding: mm(4), mm(4)
size_hint_y: None
# The column heading labels have their width set by the parent,
# but determine their height from the text.
<HeadingLabel#Label>:
bold: True
padding: dp(6), dp(4)
valign: 'bottom'
height: self.texture_size[1]
text_size: self.width, None
size_hint_y: None
<ToggleButton,Button>:
padding: dp(10), dp(8)
size_hint: None, None
size: self.texture_size
# This inherits Button and the modifications above, so reset size
<Spinner>:
size: sp(68), self.texture_size[1]
<DemoLabel#Label>:
halign: app.halign
valign: app.valign
shorten: app.shorten
max_lines: app.max_lines
canvas:
Color:
rgb: 68/255.0, 164/255.0, 201/255.0
Line:
rectangle: self.x, self.y, self.width, self.height
<StackLayout>:
size_hint_y: None
spacing: dp(6)
padding: dp(6), dp(4)
height: self.minimum_height
TYIA

How do you compacted a GridLayout vertical space in Kivy?

Have a look at the screenshot below:
I kinda new in this Kivy layout scheme, previously I work a lot in PyQt. In PyQt, that blank vertical space can easily get rid of by using Spacer. But how do you do this in Kivy? Below is part of the KV file that constitute this layout.
GridLayout:
cols: 1
GridLayout:
cols: 2
row_default_height: '48dp'
row_force_default: True
spacing: 10, 10
padding: 10, 10
Label:
size_hint: None, None
text: 'Input'
halign: 'left'
valign: 'top'
text_size: self.size
width: 50
TextInput:
id: txt_url
size_hint: 1, None
text: ''
TabbedPanel:
id: tp
do_default_tab: False
TabbedPanelItem:
id: tab_fl
text: ''
TabbedPanelItem:
text: ''
FloatLayout
id: box
TabbedPanelItem:
text: ''
FloatLayout
id: box
I Would love to know what is the best practice of using Kivy layout mechanism. :)
In this case, you can take advantage of the GridLayout's minimum_height property to size it appropriately.
GridLayout:
cols: 1
GridLayout:
cols: 2
row_default_height: '48dp'
row_force_default: True
spacing: 10, 10
padding: 10, 10
# add these two lines
size_hint_y: None
height: self.minimum_height
...
Because you're using one column width in your root GridLayout, it be possible to resize the rows based off children height using the following trick for setting rows_minimum.
GridLayout:
cols: 1
row_force_default: True
## Call it what ya like, just interested in setting 'self.rows_minimum'
foo: [self.rows_minimum.update({i: x.height}) for i, x in enumerate(reversed(list(self.children)))]
## ... rest of layout ...
The internal GridLayout and TabbedPanel are the rows/children of your root GridLayout, so setting heights for the internal elements should allow for the foo generator redirection to pull-up the excess space.
Now for readers that may have more than one column there be a more extensive example, that shows one way of handling auto-sizing of grid layouts and a bunch of other goodies, over at another answer regarding text input word wrapping.

Categories