Customise Kivy settings panel by redefining style.kv - python-3.x

I am using the default Kivy Settings widget to create a settings screen for my app. I don't want to build a custom settings widget from scratch, but I would like to customise simple properties like the text size of each item and the colour of the "close" button.
Based on the Kivy docs and the answer to this question I understand that I need to modify the styles for the different Settings class widgets that are defined in style.kv. For example, I have been able to add the following to the top of my main.py to redefine the style of the MenuSidebar widget and change the size and colour of the settings "close" button:
from kivy.lang import Builder
Builder.load_string('''
<-MenuSidebar>:
size_hint_x: None
width: '200dp'
buttons_layout: menu
close_button: button
GridLayout:
pos: root.pos
cols: 1
id: menu
padding: 5
canvas.after:
Color:
rgb: .2, .2, .2
Rectangle:
pos: self.right - 1, self.y
size: 1, self.height
Button:
text: 'Close'
id: button
size_hint: None, None
width: root.width - dp(20)
height: max(50, self.texture_size[1] + dp(20))
pos: root.x + dp(10), root.y + dp(10)
font_size: '30sp'
Following a similar approach, I now want to modify the style of each setting item so that the text colour is red. I add the following into Builder.load_string() at the top of my main.py to redefine the style of the SettingItem widget:
<-SettingItem>:
size_hint: .25, None
height: labellayout.texture_size[1] + dp(10)
content: content
canvas:
Color:
rgba: 47 / 255., 167 / 255., 212 / 255., self.selected_alpha
Rectangle:
pos: self.x, self.y + 1
size: self.size
Color:
rgb: .2, .2, .2
Rectangle:
pos: self.x, self.y - 2
size: self.width, 1
BoxLayout:
pos: root.pos
Label:
size_hint_x: .66
id: labellayout
markup: True
text: u'{0}\\n[size=13sp][color=999999]{1}[/color][/size]'.format(root.title or '', root.desc or '')
font_size: '15sp'
color: [1, 0 , 0 , 1]
text_size: self.width - 32, None
BoxLayout:
id: content
size_hint_x: .33
Everything works as expected, however the value of each setting item disappears.
I have tried everything I can think off, but I can't work out how to modify the appearance of the settings screen without losing the actual value of each setting item, or messing up the whole layout of the settings screen. Can anyone advise how I can achieve my goal?
Here is a minimal reproducible example illustrating the issue that is based on the Kivy Settings example
from kivy.app import App
from kivy.uix.settings import SettingsWithSidebar
from kivy.logger import Logger
from kivy.lang import Builder
kv = '''
BoxLayout:
orientation: 'vertical'
Button:
text: 'Configure app (or press F1)'
on_release: app.open_settings()
Label:
id: label
text: 'Hello'
<-MenuSidebar>:
size_hint_x: None
width: '200dp'
buttons_layout: menu
close_button: button
GridLayout:
pos: root.pos
cols: 1
id: menu
padding: 5
canvas.after:
Color:
rgb: .2, .2, .2
Rectangle:
pos: self.right - 1, self.y
size: 1, self.height
Button:
text: 'Close'
id: button
size_hint: None, None
width: root.width - dp(20)
height: max(50, self.texture_size[1] + dp(20))
pos: root.x + dp(10), root.y + dp(10)
font_size: '30sp'
color: [1, 0 , 0, 1]
<-SettingItem>:
size_hint: .25, None
height: labellayout.texture_size[1] + dp(10)
content: content
canvas:
Color:
rgba: 47 / 255., 167 / 255., 212 / 255., self.selected_alpha
Rectangle:
pos: self.x, self.y + 1
size: self.size
Color:
rgb: .2, .2, .2
Rectangle:
pos: self.x, self.y - 2
size: self.width, 1
BoxLayout:
pos: root.pos
Label:
size_hint_x: .66
id: labellayout
markup: True
text: u'{0}\\n[size=13sp][color=999999]{1}[/color][/size]'.format(root.title or '', root.desc or '')
font_size: '15sp'
color: [1, 0 , 0 , 1]
text_size: self.width - 32, None
BoxLayout:
id: content
size_hint_x: .33
'''
json = '''
[
{
"type": "string",
"title": "Label caption",
"desc": "Choose the text that appears in the label",
"section": "My Label",
"key": "text"
},
{
"type": "numeric",
"title": "Label font size",
"desc": "Choose the font size the label",
"section": "My Label",
"key": "font_size"
}
]
'''
class MyApp(App):
def build(self):
self.settings_cls = SettingsWithSidebar
root = Builder.load_string(kv)
label = root.ids.label
label.text = self.config.get('My Label', 'text')
label.font_size = float(self.config.get('My Label', 'font_size'))
return root
def build_config(self, config):
config.setdefaults('My Label', {'text': 'Hello', 'font_size': 20})
def build_settings(self, settings):
settings.add_json_panel('My Label', self.config, data=json)
def on_config_change(self, config, section, key, value):
Logger.info("main.py: App.on_config_change: {0}, {1}, {2}, {3}".format(
config, section, key, value))
if section == "My Label":
if key == "text":
self.root.ids.label.text = value
elif key == 'font_size':
self.root.ids.label.font_size = float(value)
def close_settings(self, settings=None):
Logger.info("main.py: App.close_settings: {0}".format(settings))
super(MyApp, self).close_settings(settings)
MyApp().run()

Add this to your kv string:
<SettingString>:
Label:
text: root.value or ''
pos: root.pos
font_size: '15sp'
color: 1,0,0,1
Color obviously can be whatever you want.
this only works for the settings string, if you use other settings objects modify them in a similar way :)

Related

Where should methods be placed; ids vs NumericProperty; kivy

I have a very basic kivy code. I have the .py file and the .kv file. The questions are: where should the methods be placed? In this example the 2 methods that interact are 'def GetTicker(ticker):' and 'def GetTickers(self):'. I have placed both outside of any class, because I could not get the code to work otherwise; however I think the proper way to code would be to place them inside the 'app' class.
As an aside I am very confused about where/when the 'self' should be passed. I'm working by trial and error here.
Then there is the 'NumericProperty'. I read here that when it is updated, it automatically updates the widgets that are associated with it. It doesn't for me, therefore I had to create Id's for some labels; but the id's won't work at the beginning of the run, only on update.
I'm using python 3.9 and kivy 2.0.0, PyCharm 2021.3.1 (Community Edition) on win10 box.
Any and all assistance will be greatly appreciated.
Ray
the .py file
from kivy.app import App
from kivy.properties import NumericProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.textinput import TextInput
from kivy.core.window import Window
Window.size = (300, 300)
import time
from yahoo_fin.stock_info import get_live_price # This API only gets the live price
from yahoo_fin import stock_info as si # This is SLOWER than the above API, buts gets more info
class MyBoxLayout(BoxLayout):
def __init__(self, **kwargs):
super().__init__(**kwargs)
def press(self):
name = self.ids.ticker_name.text.upper()
self.ids.ticker_value.text = self.GetTicker(name)
def update(self):
#GetTickers(self) # This won't work here :(
self.ids.mydow_price.text, self.ids.mydow_chg = self.GetTicker("^DJI")
self.ids.mysp_price.text, self.ids.mysp_chg = self.GetTicker("^GSPC")
self.ids.mynasdaq_price.text, self.ids.mynasdaq_chg.text = self.GetTicker("^IXIC")
self.ids.myeuro_price, self.ids.myeuro_chg.text = self.GetTicker("EURUSD=X")
#print(self.ids.amazon_id.text)
class MyOtherBoxlayout(BoxLayout):
pass
class MyTicker(TextInput):
pass
class gridlayout(GridLayout):
pass
def GetTicker(ticker):
# data = get_live_price(ticker)
data = si.get_quote_table(ticker)
price = data['Quote Price']
change = price - data['Previous Close']
# print("Price: %.3f" % price)
# print("Change: %.3f" % change)
return [str("%s" % format(price, ',.3f')), str("%s" % format(change, ',.3f'))]
def GetTickers(self):
self.dow_price, self.dow_chg = self.GetTicker("^DJI")
self.sp_price, self.sp_chg = self.GetTicker("^GSPC")
self.nasdaq_price, self.nasdaq_chg = self.GetTicker("^IXIC")
self.euro_price, self.euro_chg = self.GetTicker("EURUSD=X")
# This is the app class
class StockTickerApp(App):
def __init__(self, **kwargs):
super().__init__(**kwargs)
App.title = "Ray's Stock Ticker"
dow_price = NumericProperty(0.00)
dow_chg = NumericProperty(0.00)
sp_price = NumericProperty(0.00)
sp_chg = NumericProperty(0.00)
nasdaq_price = NumericProperty(0.00)
nasdaq_chg = NumericProperty(0.00)
euro_price = NumericProperty(0.00)
euro_chg = NumericProperty(0.00)
start_time = time.time()
self.GetTickers()
end_time = time.time()
print (end_time - start_time)
# and its run here
StockTickerApp().run()
the .kv file
MyBoxLayout:
<MYLabel#ButtonBehavior+Label>: # this is something I found that helps make a label behave
# like a button.
<MyBoxLayout>:
canvas.before:
Color:
rgba: (153/255, 255/255, 255/255, 1)
Rectangle:
pos: self.pos
size: self.size
padding: ("15dp", "15dp", "15dp", "15dp") #left, top, right, bottom
spacing: "10dp"
orientation: "vertical"
#
# 1st widget
#
Label:
text: "Stocks Ticker"
size_hint: 1, .1
#pos_hint: {"top": 1}
color:0,0,0,1
#
# 2nd widget
#
BoxLayout:
canvas.before:
Color:
rgba: (19/255,202/255,55/255,1) # lime more intense
Rectangle:
pos: self.pos
size: self.size
padding: ("10dp", "0dp", "15dp", "0dp")
spacing: "20dp"
orientation: "horizontal"
size_hint: 1, .4
#pos_hint: {"center": .5}
Label:
text: " Enter Stock"
size_hint: .6, .5
pos_hint: {"center_X":.5, "top": .7}
color: 72/255,89/255,89/255,1
MyTicker: # this is a textinput widget
id: ticker_name
text: ""
size_hint: .6, .6
pos_hint: {"top": .8}
Label:
id: ticker_value
#text: " Enter Stock"
size_hint: .5, .1
color: 0,0,0,1
pos_hint: {"top":.5, "center": 1}
#
# 3rd widget
#
BoxLayout:
size_hint: 1, .3
Button:
#id: "Find_Value"
text: "Find Value"
on_press: root.press()
#
# 4th widget
#
gridlayout:
canvas.before:
Color:
rgba: (19/255,202/255,55/255,1) # lime more intense
Rectangle:
pos: self.pos
size: self.size
rows: 4
cols: 3
padding: "10dp"
MYLabel:
color: 72/255,89/255,89/255,1
text: "Dow"
text_size: self.size
halign: 'left'
on_press: root.update()
MYLabel:
id: mydow_price
color: 0,0,0,1
text: app.dow_price
text_size: self.size
halign: 'right'
on_press: root.update()
MYLabel:
id: mydow_chg
color: 0,0,0,1
text: app.dow_chg
text_size: self.size
halign: 'right'
on_press: root.update()
MYLabel:
text: "S&P 500"
color: 72/255,89/255,89/255,1
text_size: self.size
halign: 'left'
on_press: root.update()
MYLabel:
id: mysp_price
text: app.sp_price
color: 0,0,0,1
text_size: self.size
halign: 'right'
MYLabel:
id: mysp_chg
text: app.sp_chg
color: 0,0,0,1
text_size: self.size
halign: 'right'
MYLabel:
text: "Nasdaq"
color: 72/255,89/255,89/255,1
text_size: self.size
halign: 'left'
on_press: root.update()
MYLabel:
id: mynasdaq_price
text: app.nasdaq_price
color: 0,0,0,1
text_size: self.size
halign: 'right'
MYLabel:
id: mynasdaq_chg
text: app.nasdaq_chg
color: 0,0,0,1
text_size: self.size
halign: 'right'
MYLabel:
text: "Euro/USD"
color: 72/255,89/255,89/255,1
text_size: self.size
halign: 'left'
on_press: root.GetTickers()
MYLabel:
id: myeuro_price
text: app.euro_price
color: 0,0,0,1
text_size: self.size
halign: 'right'
MYLabel:
id: myeuro_chg
text: app.euro_chg
color: 0,0,0,1
text_size: self.size
halign: 'right'

How to add multiple widget at the same time to a scrollview?

I'm new at kivy, so I'm working on a test app. I want to create a screen with ScrollView and I want to add multiple things to a 'line' in the ScrollView, a text (description) and an image.
I have tried this way:
class PresentUploadedData(Screen):
container = ObjectProperty(None)
def __init__(self, **kwargs):
super(PresentUploadedData, self).__init__(**kwargs)
Clock.schedule_once(self.setup_scrollview, 1)
def setup_scrollview(self, dt):
self.container.bind(minimum_height=self.container.setter('height'))
self.add_text_inputs()
def add_text_inputs(self):
for x in range(30):
self.container.add_widget(Label(text="Label {}".format(x), size_hint_y=None, height=40, color= [128,0,0,1]))
self.container.add_widget(Image(source='test.jpg', size_hint=(None, None,), width=50, height=50))
with this .kv file:
<PresentUploadedData>:
name: "presentupload"
message: send
container: container
canvas:
Color:
rgba: 1,1,1,1
Rectangle:
size: self.size
pos: self.pos
GridLayout:
rows: 3
cols: 1
spacing: 5
padding: 5
font_name: "Calibri"
background_color: 1,1,1, 1
ScrollView:
background_color: 1,1,1, 1
size_hint: (1, .9)
bar_width: 10
bar_color: 128,0,0,0.7
bar_inactive_color: 128,0,0,1
effect_cls: "ScrollEffect"
scroll_type: ['bars', 'content']
color: 128,0,0,1
StackLayout:
id: container
size_hint_y: None
color: 128,0,0,1
GridLayout:
cols: 2
BoxLayout:
spacing: 5
size_hint: .7, .1
Button:
text: "< BACK"
id: send
color: 0, 0, 0, 1
background_color: .88,.88,.88, 1
size_hint: .2, 1
on_release:
app.root.current = "main"
root.manager.transition.direction = "right"
But I've got ScrollView accept only one widget Exception.
Why I got this, and how can I resolve this?
There is an error in .kvfile:
GridLayout:
cols: 2
This is useless.
The problem can be solved with one more for inside the for loop:
row = [Label(text="Label {}".format(x), size_hint_y=None, height=50, color= [128,0,0,1]), Image(source='test.jpg', size_hint=(None, None,), width=50, height=50)]
for r in row:
self.container.add_widget(r)
But this also didn't put the things near each other, just let them be there.

Kivy - How to Size Embedded Anchor Layouts?

I would like to build the following simple design in a .kv file.
It is made of 3 parts :
One top-left Anchor Layout which is made up of a Grid Layout of 3 columns. I want its width to be equal to 20% of the window's with and its height to be equal to 75% of the window's height.
One top-right Anchor Layout which is made up of a vertically-oriented Box Layout. I want its width to be equal to 80% of the window's with and its height to be equal to 75% of the window's height.
One bottom-left Anchor Layout which is empty for the moment. I want its height to be 25% of the window's height.
These three parts are themselves included in an AnchorLayout.
I tried to translate this design into a .kv file as follows.
#:kivy 1.11.1
<Example>:
anchor_x: "center"
anchor_y: "center"
AnchorLayout:
anchor_x: "left"
anchor_y: "top"
size_hint: (0.2, 0.75)
GridLayout:
cols: 3
Button:
text: "X"
Button:
text: "X"
Button:
text: "X"
Button:
text: "X"
Button:
text: "X"
Button:
text: "X"
AnchorLayout:
anchor_x: "right"
anchor_y: "top"
size_hint: (0.8, 0.75)
BoxLayout:
orientation: "vertical"
Label:
text: "HELLO..."
Label:
text: "WORLD..."
AnchorLayout:
anchor_x: "left"
anchor_y: "bottom"
size_hint: (1, 0.25)
Label:
text: "FOOTER"
In case it matters, here is the code of my .py file as well.
# Importing Kivy
import kivy
kivy.require("1.11.1")
# Importing kivy libraries
from kivy.app import App
from kivy.uix.anchorlayout import AnchorLayout
from kivy.lang import Builder
# Importing external libraries
# Import kv files
Builder.load_file("example.kv")
# Root widget of the application
class Example(AnchorLayout):
pass
# Application class
class TestApp(App):
def build(self, **kwargs):
return Example()
# Launch the application
if __name__=="__main__":
app = TestApp()
app.run()
The output does not look as I expected as shown on the picture below :
I don't get it. Because the AnchorLayout is a subclass of the Widget class and is itself included within a Layout, its size_hint property should enable me to define its size.
What am I missing here ? Thanks in advance!
Problem - design centered
The design is placed in the center.
Root Cause
The root is an AnchorLayout with value 'center' for both anchor_x and anchor_y. Therefore, all its children (the AnchorLayouts) are placed in respect to the root.
Below is a view of your design in different colours for visualization.
AnchorLayout
The AnchorLayout aligns its children to a border (top, bottom, left, right) or center.
Solution
There are three possible solutions to your design. The preference is method 1.
Method 1 - No AnchorLayouts
This method replace all AnchorLayouts with BoxLayouts. It use one less AnchorLayout widget which makes the app more resource efficient i.e. use less memory and the app is smaller.
Snippets - Method 1
<Example>:
orientation: 'vertical'
BoxLayout:
...
GridLayout: # left box
...
BoxLayout: # right box
...
BoxLayout: # footer
...
Method 2 - BoxLayout as root
This method replace the root widget with BoxLayout and realign the left box.
Snippets - Method 2
<Example>:
orientation: 'vertical'
AnchorLayout:
...
GridLayout: # left box
...
AnchorLayout: # right box
...
AnchorLayout: # footer
...
Method 3
This method add a BoxLayout as a child of the root, and the rest of the AnchorLayout as children of the BoxLayout.
Snippets - Method 3
<Example>:
anchor_x: "center"
anchor_y: "center"
BoxLayout:
orientation: 'vertical'
AnchorLayout:
...
GridLayout: # left box
...
AnchorLayout: # right box
...
AnchorLayout: # footer
...
Example
Method 1 - No AnchorLayouts
main.py
from kivy.base import runTouchApp
from kivy.lang import Builder
runTouchApp(Builder.load_string("""
BoxLayout:
orientation: 'vertical'
BoxLayout:
size_hint: 1, 0.75
GridLayout:
size_hint: 0.2, 1
canvas.before:
Color:
rgba: 1, 0, 0, 1
Rectangle:
size: self.size
pos: self.pos
cols: 3
row_force_default: True
row_default_height: 40
Button:
text: "X"
Button:
text: "X"
Button:
text: "X"
Button:
text: "X"
Button:
text: "X"
Button:
text: "X"
BoxLayout:
orientation: 'vertical'
canvas.before:
Color:
rgba: 0, 1, 0, 1
Rectangle:
size: self.size
pos: self.pos
Label:
text: "HELLO..."
Label:
text: "WORLD..."
BoxLayout:
size_hint: 1, 0.25
canvas.before:
Color:
rgba: 0, 0, 1, 1
Rectangle:
size: self.size
pos: self.pos
Label:
text: "FOOTER"
"""))
Output: Method 1 - No AnchorLayouts
Method 2 - BoxLayout as root
main.py
from kivy.base import runTouchApp
from kivy.lang import Builder
runTouchApp(Builder.load_string("""
BoxLayout:
orientation: 'vertical'
AnchorLayout:
size_hint: 1, 0.75
anchor_x: 'left'
anchor_y: 'top'
GridLayout:
size_hint: 0.2, 1
canvas.before:
Color:
rgba: 1, 0, 0, 1
Rectangle:
size: self.size
pos: self.pos
cols: 3
row_force_default: True
row_default_height: 40
Button:
text: "X"
Button:
text: "X"
Button:
text: "X"
Button:
text: "X"
Button:
text: "X"
Button:
text: "X"
AnchorLayout:
anchor_x: 'right'
anchor_y: 'top'
BoxLayout:
orientation: 'vertical'
size_hint: 0.8, 1
canvas.before:
Color:
rgba: 0, 1, 0, 1
Rectangle:
size: self.size
pos: self.pos
Label:
text: "HELLO..."
Label:
text: "WORLD..."
AnchorLayout:
size_hint: 1, 0.25
anchor_x: 'left'
anchor_y: 'bottom'
canvas.before:
Color:
rgba: 0, 0, 1, 1
Rectangle:
size: self.size
pos: self.pos
Label:
text: "FOOTER"
"""))
Output: Method 2 - BoxLayout as root
Changing the Example class to extend FloatLayout instead of AnchorLayout allows more control of its children. With that change to Example, here is a kv that looks more like what you want:
<Example>:
AnchorLayout:
anchor_x: "center"
anchor_y: "top"
size_hint: (0.2, 0.75)
pos_hint: {'x':0, 'top':1}
GridLayout:
cols: 3
Button:
text: "X"
Button:
text: "X"
Button:
text: "X"
Button:
text: "X"
Button:
text: "X"
Button:
text: "X"
AnchorLayout:
anchor_x: "center"
anchor_y: "top"
size_hint: (0.8, 0.75)
pos_hint: {'right':1, 'top':1}
BoxLayout:
orientation: "vertical"
Label:
text: "HELLO..."
Label:
text: "WORLD..."
AnchorLayout:
anchor_x: "center"
anchor_y: "bottom"
size_hint: (1, 0.25)
pos_hint: {'x':0, 'y':0}
Label:
text: "FOOTER"

Page layout - resetting the page in Kivy / Python

I'm just getting started with Kivy programming for Python. I'm having trouble in using the PageLayout. This is my Python Code so far (Python 3.6.2):
import kivy
from kivy.app import App
from kivy.uix.pagelayout import PageLayout
class PageApp(App):
def build(self):
return PageLayout()
paApp = PageApp()
paApp.run()
The Kivy-file (PageApp.kv) has the following content:
<PageLayout>:
canvas:
Color:
rgb: 0, .5, .95
Rectangle:
pos: self.pos
size: self.size
BoxLayout:
orientation: "vertical"
Button:
text: "This is a test button"
size_hint_y: .4
Label:
markup: True
text: "This is a [b]looooong[/b] text... "*100
color: 0, 0, 0, 1
outline_color: 0, 0.5, 0.5, 1
font_size: 30
BoxLayout:
orientation: "vertical"
Label:
markup: True
text: "This is an even [b]looooonger[/b] text... "*100
color: 0, 0, 0, 1
outline_color: 0, 0.5, 0.5, 1
font_size: 30
Button:
text: "This is a second test button"
size_hint_y: .2
Button:
text: "Page 3"
Button:
text: "Page 4"
The result looks like this: Page 1, Page 2 (after swiping)
As is visible from the screenshots, the following problems appear:
The Labels don't show.
The background is only partially in the color that I specified in the canvas-settings.
Most importantly: the page doesn't seem to reset after swiping, leading to the problem that elements from the first page remain on the page when swiping to page 2. Page 3 and 4 seem to work fine, because the buttons take the whole space...
Does anyone know how to fix these issues?
Please refer to the example below for details.
Question The Labels don't show.
Answer The two Labels did show up but as black labels because you have exceeded the text size.
In page 1, I have changed the multiplication value from 100 to 49. Anything 50 and above, you will see a black label.
In page 2, I have removed 100. Anything between 2 and 36, the text overflowed into page 1. Anything 37 and above, you will see a black label.
Question The background is only partially in the color that I specified in the canvas-settings.
Answer The color of the canvas was not set for page 2. Therefore, it is using the color from page 1.
Question Most importantly: the page doesn't seem to reset after swiping, leading to the problem that elements from the first page remain on the page when swiping to page 2. Page 3 and 4 seem to work fine, because the buttons take the whole space...
Answer You will see border areas on the right or left hand side which is use for swiping from one page to the next.
Example
main.py
from kivy.app import App
from kivy.uix.pagelayout import PageLayout
class PageLayoutDemo(PageLayout):
pass
class TestApp(App):
title = "Kivy PageLayout Demo"
def build(self):
return PageLayoutDemo()
if __name__ == "__main__":
TestApp().run()
test.kv
#:kivy 1.10.0
<PageLayoutDemo>:
BoxLayout:
canvas:
Color:
rgb: 0, .5, .95, 1
Rectangle:
pos: self.pos
size: self.size
orientation: "vertical"
Button:
text: "This is a test button"
size_hint_y: .4
Label:
markup: True
text: "This is a [b]looooong[/b] text... " * 49
color: 0, 0, 0, 1
outline_color: 0, 0.5, 0.5, 1
font_size: 30
BoxLayout:
orientation: "vertical"
canvas:
Color:
rgba: 109/255., 8/255., 57/255., 1
Rectangle:
pos: self.pos
size: self.size
Label:
markup: True
text: "This is an even [b]looooonger[/b] text... "
color: 0, 0, 0, 1
outline_color: 0, 0.5, 0.5, 1
font_size: 30
Button:
text: "This is a second test button"
size_hint_y: .2
Button:
text: "Page 3"
Button:
text: "Page 4"
Output
Okay
you don't set the text_size property of the label and the text that you want to show is very long
Sorry but the background color is exactly the color that you specified in the canvas, see the image below
You can set the border property of the PageLayout if you want to reduce the size of the next/previews page in the current
If you just want a widget to swipe arround sub widgets I suggest you to use the Caroussel widget
Try the code below:
-main.py
import kivy
from kivy.app import App
from kivy.uix.pagelayout import PageLayout
class PageApp(App):
def build(self):
return PageLayout()
paApp = PageApp()
paApp.run()
-page.kv
<PageLayout>:
border: 5
BoxLayout:
canvas:
Color:
rgb: 0, .5, .95
Rectangle:
pos: self.pos
size: self.size
orientation: "vertical"
Button:
text: "This is a test button"
size_hint_y: .4
Label:
markup: True
text: "This is a [b]looooong[/b] text... " * 100
text_size: self.size
color: 0, 0, 0, 1
outline_color: 0, 0.5, 0.5, 1
font_size: 30
BoxLayout:
canvas:
Color:
rgb: 0, .5, .95
Rectangle:
pos: self.pos
size: self.size
orientation: "vertical"
Label:
markup: True
text: "This is an even [b]looooonger[/b] text... " * 100
color: 0, 0, 0, 1
outline_color: 0, 0.5, 0.5, 1
font_size: 30
text_size: self.size
Button:
text: "This is a second test button"
size_hint_y: .2
Button:
canvas.before:
Color:
rgb: 0, .5, .95
Rectangle:
pos: self.pos
size: self.size
text: "Page 3"
Button:
canvas.before:
Color:
rgb: 0, .5, .95
Rectangle:
pos: self.pos
size: self.size
text: "Page 4"
-some outputs:
proof for the background color:
I hope this helps !

why is text in Kivy spinner vague / blurry

I have a spinner used to select items as dropdown. The text in the textfield itself is normal. But the text in the spinner items looks blurry/vague, see the attached image. How could I resolve this?
The source file qmonos.py:
from kivy.app import App
from kivy.core.window import Window
from kivy.uix.boxlayout import BoxLayout
class qmonosHome(BoxLayout):
def init_qmonos(self):
self.objtype.text = ''
self.objtype.values = ('Home', 'Work', 'Other', 'Custom')
class qmonosApp(App):
def build(self):
Window.clearcolor = (.95,.95,.95,1)
Window.size = (800, 200)
homeWin = qmonosHome()
homeWin.init_qmonos()
return homeWin
qmonosApp().run()
The kivy file qmonos.kv
# File: qmonos.kv
#:import Factory kivy.factory.Factory
#:set color_button (.5,1,1,1)
#:set color_button_pressed (0.7,0.9,1,1)
#:set color_font (1,1,1,1)
<MySpinnerOption#SpinnerOption>:
background_color: color_button if self.state == 'down' else color_button_pressed
color: color_font
font_size: 12
text_size: self.width - 10, self.height
height: 25
<qmonosHome>:
objtype:objtype
BoxLayout:
orientation: "horizontal"
padding: 10,10,10,10
BoxLayout
orientation: "vertical"
size_hint: 0.5,1
BoxLayout:
orientation: "horizontal"
height: "20dp"
size_hint_y: None
Label:
text: "Hello World"
size_hint: 1,1
size: self.texture_size
halign: 'left'
valign: 'middle'
font_size: 12
color: .3,.3,.3,1
BoxLayout
orientation: "vertical"
size_hint: 0.5,1
padding: 10,0,10,0
BoxLayout:
orientation: "horizontal"
height: "20dp"
size_hint_y: None
Label:
text: "Type Object:"
size_hint: 0.25,1
size: self.texture_size
halign: 'left'
valign: 'middle'
font_size: 12
color: .3,.3,.3,1
Spinner:
id: objtype
text: ''
background_color: color_button if self.state == 'normal' else color_button_pressed
color: color_font
option_cls: Factory.get("MySpinnerOption")
font_size: 12
text_size: self.width - 10, self.height
size_hint: 0.25,1
multiline: False
foreground_color: .3,.3,.3,1
disabled_foreground_color: .3,.3,.3,1
Label:
text: "Hello too"
size_hint: 0.5,1
size: self.texture_size
halign: 'left'
valign: 'middle'
font_size: 12
color: .3,.3,.3,1
This is a known issue in Kivy, that apparently hasn't been fixed yet. Refer to those links for more info on this case: GitHub, Google Groups, Bountysource. They tell that the issue is that the text is not drawn on the whole pixel, but rather on a part of it.
An unexpected solution in your case: mess around with the padding. Is it important for the padding to be exactly 10? Because I've found out that (12, 12, 12, 12) works perfectly and the text is sharp. That's kinda strange, but I hope it works for you. That's as far as I can help you with this problem.
You could address this issue to Kivy devs, but considering it was discovered in 2014, I'm surprised it wasn't fixed.

Resources