KivyMD: set text on top of TextField - python

As the image below, I'm trying to set the text on the top of textField.
There's too many space between the text (above and below), so I'd like to set the text more close to the top line.
I already tried to search on kivy's documentation and here on the site, but not something helpful.
Code:
from kivymd.app import MDApp
from kivymd.uix.floatlayout import FloatLayout
from kivymd.uix.textfield import MDTextField
from kivy.lang import Builder
KV = '''
ScreenManager:
Screen:
BoxLayout:
orientation: 'vertical'
Screen:
<Screen>:
ScrollView:
MDList:
spacing: '10dp'
padding: '25dp'
MDTextField:
halign: 'center'
multiline: True
font_size: self.width / 25
MDTextField:
halign: 'center'
font_size: self.width / 25
mode: 'rectangle'
multiline: True
MDTextField:
halign: 'center'
font_size: self.width / 25
multiline: True
mode: 'fill'
'''
class Screen(FloatLayout):
pass
class Aplicativo(MDApp):
def build(self):
return Builder.load_string(KV)
Aplicativo().run()
I'm sorry if I was not comprehensive.

Related

Add widget dynamically from outside class (error)

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

KivyMD MDRectangleFlatIconButton's text is in two lines when text is updated with a long text

I want to update MDRectangleFlatIconButton's text. It changes with a new text but when the new text is longer than previous text, then the text fits in two lines.
When i use a normal button, the new text fits in one line with proper adjustment.
but Since there is a Icon in MDRectangleFlatIconButton, when a new text is longer than previous text, the text fits in a two line.
To run the program,
Add a new app name which is longer than "Info" inside "Info" button's popup window, then click "Update Top Bar's name". Then, it updated title and the text of "Info" button at the front main App.
I have tried to change this by adding button's text_size: self.width, valign:"center", haling: "center", or manually adding text_size: cm(10), cm(10).
Also, i tried with on_release: "app.root.ids.bt_information.text_size = self.width, None
but nothing works so far.
I greatly appreciate your help.
Python code
'''
from kivy.uix.widget import Widget
'''Setting the size of first window for program'''
from kivy.config import Config #another way of setting size of window
Config.set('graphics', 'width', '600') # from kivy.core.window import Window
Config.set('graphics', 'height', '750') # Window.size = ("600", "750")
from kivymd.app import MDApp
from kivy.lang import Builder
from kivy.factory import Factory
from kivy.uix.popup import Popup
from kivy.properties import ObjectProperty
Builder.load_file('new_window_popup.kv')
class Dex(Popup):
pass
class Remi(Popup):
pass
class Info(Popup):
pass
class MyLayout(Widget):
pass
class AwesomeApp(MDApp):
def build(self):
self.title = "My house"
return MyLayout()
if __name__ == '__main__':
AwesomeApp().run()
'''
kivyfile: new_window_popup.kv
'''
#:import Factory kivy.factory.Factory
#:import MDRaisedButton kivymd.uix.button
<Dex>:
auto_dismiss: False
size_hint: 1, 1
title: "Weight-Based Dose Calculator "
canvas.before:
Color:
rgba: (0,1,0,1)
Rectangle:
pos:self.pos
size:self.size
BoxLayout:
orientation: "vertical"
size:root.width, root.height
Label:
text: "Dex 1"
Button:
text: "Close"
font_size: 24
on_release: root.dismiss()
<Remi>:
auto_dismiss: False
size_hint: 1, 1
title: "Weight-Based Dose Calculator "
canvas.before:
Color:
rgba: (0,1,0,1)
Rectangle:
pos:self.pos
size:self.size
BoxLayout:
orientation: "vertical"
size:root.width, root.height
Label:
text: "Remi"
Button:
text: "Close"
font_size: 24
on_release: root.dismiss()
<Info>:
appName:appName
auto_dismiss: False
size_hint: 1, 1
title: "Change Info"
canvas.before:
Color:
rgba: (0,1,0,1)
Rectangle:
pos:self.pos
size:self.size
BoxLayout:
orientation: "vertical"
size:root.width, root.height
Label:
text: "What is your App name?"
BoxLayout:
orientation: "horizontal"
MDTextField:
id: appName
hint_text: "App Name"
color_mode: 'primary'
current_hint_text_color: 1,1,1,1
hint_text_color_focus: 1,1,1,.9
line_color_focus: 1,1,1,1
font_size: '25sp'
text_color_normal: 1,1,1,.9
text_color_focus: 0,0,1,.9
focus: True
write_tab: False
Button:
text: "Update Top Bar\'s name"
font_size: 24
size_hint: .8, .2
# on_release: root.updateName()
on_release:
app.title = appName.text
app.root.ids.bt_information.text = appName.text
Button:
text: "Close"
font_size: 24
on_release: root.dismiss()
<MyLayout>
MDBoxLayout:
orientation:"vertical"
size: root.width, root.height
MDRaisedButton:
text: "Dex"
font_size: 32
text_color: 0,0,0,.9
size_hint: 1,.5
on_press: Factory.Dex().open()
MDRaisedButton:
text: "Remi"
font_size: 32
size_hint: 1,.5
on_press: Factory.Remi().open()
MDRectangleFlatIconButton:
id: bt_information
text: "Info"
icon: "youtube-studio"
font_size: 32
size_hint: 1,.2
text_size: self.width, None
md_bg_color: 0.95,0.61,0.73,1
on_press: Factory.Info().open()
'''

python kivy screen confog

main.py file
from kivymd.app import MDApp
from kivy.lang import Builder
class Hero(MDApp):
def build(self):
return Builder.load_file("stackoverflow.kv")
Hero().run()
the above is the main.py file
please guys help me with this
stackoverflow.kv file
ScreenManager:
id: screenmanager
Screen:
id: accountscreen
name: "screen1"
BoxLayout:
oreintation: "vertical"
MDGridLayout:
cols:1## Heading ##
MDLabel:
text: "[color=00FF00]Sign In[/color]"
bold:True
markup:True
halign: "center"
valign: "middle"
MDTextField:
id: username
padding: "30dp"
spacing: "30dp"
hint_text:"User Name or Email"
pos_hint: {"center_x":.5,"center_y":.5}
MDTextField:
id:password
padding: "20dp"
spacing: "20dp"
hint_text:"Password"
MDRectangleFlatButton:
text:"Sign In"
padding: "16dp"
spacing: "16dp"
halign: "center"
pos_hint: {"center_x":.9,"center_y":.5}
on_press: app.root.current="screen2"
BoxLayout:
oreintation: "vertical"
Screen:
id: welcome_screen
name: "screen2"
MDLabel:
text: "welcome"
valign: "middle"
halign: "center"
any time i open the app i get the sign in screen how can i save the user information and clear the screen using config ini file please help me????
Here is a version of you code that uses Config to do what you want:
import os
from kivymd.app import MDApp
from kivy.lang import Builder
class Hero(MDApp):
def build(self):
sm = Builder.load_file("stackoverflow.kv")
self.load_my_config()
sm.current = self.initial_screen
return sm
def build_config(self, config):
# Make sure that the config has at least default entries that we need
config.setdefaults('app', {
'startup_screen': 'screen1',
})
def get_application_config(self):
# This defines the path and name where the ini file is located
return str(os.path.join(os.path.expanduser('~'), 'Hero.ini'))
def on_stop(self):
# save the config when the app exits
self.save_config()
def save_config(self):
# this writes the data we want to save to the config
# set the data in the config
self.config.set('app', 'startup_screen', 'screen2')
# write the config file
self.config.write()
def load_my_config(self):
# extract our saved data from the config (it has already been read)
self.initial_screen = self.config.get('app', 'startup_screen', fallback='screen1')
Hero().run()
And in the kv file, I would add a call to save the configuration when the Sign In button is pressed:
MDRectangleFlatButton:
text:"Sign In"
padding: "16dp"
spacing: "16dp"
halign: "center"
pos_hint: {"center_x":.9,"center_y":.5}
on_press:
app.root.current="screen2"
app.save_config()

How to show languange specific characters on Kivy like Ä?

Im getting empty box character instead of Ä character. How to make them show on my kivy application. I read some posts suggesting changing font type to some which support these characters. i tried few but it didnt seem solving it.
Tried pretty basic Calibri font and also just randomly picked font which was said to be suitable with my languange( AlegreyaSansSC)
Python file:
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.popup import Popup
from kivy.uix.button import Button
from kivy.uix.screenmanager import Screen, ScreenManager
from kivy.properties import StringProperty, BooleanProperty
class Row(BoxLayout):
x1 = StringProperty('')
x2 = StringProperty('')
x3 = BooleanProperty(False)
def __init__(self, x1, x2, x3, **kwargs):
super(Row, self).__init__(**kwargs)
self.x1 = x1
self.x2 = x2
self.x3 = x3
class MyPopup(Popup):
pass
class MainScreen(Screen):
pass
class SecondScreen(Screen):
def fire_popup(self):
pops = MyPopup()
pops.open()
class ScreenManagement(ScreenManager):
def changescreen(self, value):
try:
if value !='main':
self.current = value
except:
print('No Screen named'+ value)
class testiApp(App):
def build(self):
self.title = 'Hello'
def add_more(self, x1, x2, x3):
addbutton = self.root.get_screen('Page2').ids.empty
addbutton.add_widget(Row(x1, x2, x3))
def remove(self):
container = self.root.get_screen('Page2').ids.empty
if len(container.children) > 0:
container.remove_widget(container.children[0])
testiApp().run()
KV. file:
<MyPopup>:
id:pop
size_hint: .4, .4
auto_dismiss: False
title: 'XXX!!'
BoxLayout:
orientation:'vertical'
BoxLayout:
orientation:'horizontal'
Label:
text:'X1'
TextInput:
id: X1
Label:
text:'X2'
TextInput:
id:X2
CheckBox:
id:X3
BoxLayout:
orientation:'horizontal'
Button:
text:'Lisää'
on_release: app.add_more(X1.text, X2.text, X3.active)
Button:
text: 'Close'
on_press: pop.dismiss()
<Row>:
x1:''
x2:''
x3:False
Label:
text: root.x1
Label:
text: root.x2
CheckBox:
active: root.x3
ScreenManagement:
MainScreen:
name:'Main'
SecondScreen:
name:'Page2'
<MainScreen>:
name:'Main'
BoxLayout:
Button:
text:'Next Page'
on_release: app.root.current ='Page2'
<SecondScreen>:
name:'Page2'
BoxLayout:
orientation:'vertical'
BoxLayout:
orientation:'vertical'
Label:
text:'Popup Test'
ScrollView:
bar_width: 5
bar_color: 1,0,0,1 #red
bar_inactive_color: 0,0,1,1 #blue
effect_cls: 'ScrollEffect'
scroll_type:['bars','content']
GridLayout:
orientation: "vertical"
size_hint_y: None
height: self.minimum_height
row_default_height: 60
cols:1
id:empty
BoxLayout:
Button:
text:'Open Popup'
on_press: root.fire_popup()
Button:
text:'Add'
on_release: app.add_more()
Button:
text:'remove'
on_release: app.remove()
Question
Seems that problem happens only if i use separate py. and kv file.
Answer
I don't think the problem is caused by separate py and kv file. The following example displayed the character correctly.
main.py
from kivy.base import runTouchApp
from kivy.lang import Builder
runTouchApp(Builder.load_file("main.kv"))
main.kv
GridLayout:
cols: 2
Label:
text: 'Alegreya Sans SC font'
Label:
text: 'Roboto font (Default)'
Label:
text: 'Ä'
font_size: 56
font_name: '/home/iam/share/fonts/Alegreya_Sans_SC/AlegreyaSansSC-Medium.ttf'
Label:
text: 'Ä'
font_size: 56
Problem
I'm getting empty box character instead of Ä character. How to make
them show on my kivy application.
Solution
Download and extract Alegreya Sans SC font from Google Fonts. This font is under Open Font License
Add attribute, font_name: and provide the path to the extracted folder plus the type of font (e.g. AlegreyaSansSC-Medium.ttf).
Example
The following example illustrates displaying character, Ä using attribute, font_name to use different font. The default font use by Kivy is Roboto.
main-kv.py
from kivy.base import runTouchApp
from kivy.lang import Builder
runTouchApp(Builder.load_string("""
GridLayout:
cols: 2
Label:
text: 'Alegreya Sans SC font'
Label:
text: 'Roboto font (Default)'
Label:
text: 'Ä'
font_size: 56
font_name: '/home/iam/share/fonts/Alegreya_Sans_SC/AlegreyaSansSC-Medium.ttf'
Label:
text: 'Ä'
font_size: 56
"""))
Output

AssertionError in Python / Kivy

I came across an AssertionError for a kivy script. The codes as follows:
import time
from copy import deepcopy as dc
# import modules related to kivy UI
from kivy.app import App
# kivy.require("1.9.1")
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.lang import Builder
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.image import Image
# define global variables just for testing
temperature = str(25)+"°C"
humidity = str(95)+'%'
last_water = "15/04/2018 15:40"
time_next = str(4)+' hr'
kv = """
<LeftScreen>:
GridLayout:
cols: 2
Image:
id: im
source: 'C:/Users/Acer/Documents/Python Scripts/sakura.jpg'
size_hint: 0.5, 0.5
Label:
id: title
text: '[b][i]Smart[/i]'+' Gardener[/b]'
color: (0.25,0.5,0.1,1)
font_size: 60
font_name: 'times'
Label:
id: group
text: '[i]group 8[/i]'
color: (0.3,0.3,0.6,1)
font_size: 45
font_name: 'Arial'
valign: 'bottom'
Label:
id: lastU
text: '[i]'+'Last Update: '+time.striftime("%H:%M:%S")+'[/i]'
font_size: 18
halign: 'center'
valign: 'middle'
Button:
id: update
text: 'Refresh'
font_size: 20
halign: 'center'
valign: 'middle'
on_press: root.reload()
Label:
id: temp_lbl
text: 'Temperature: '
font_size: 24
halign: 'center'
valign: 'middle'
Label:
id: temp_val
text: root.temp
font_size: 24
halign: 'center'
valign: 'middle'
Label:
id: hum_lbl
text: 'Humidity: '
font_size: 24
halign: 'center'
valign: 'middle'
Label:
id: hum_val
text: root.hum
font_size: 24
halign: 'center'
valign: 'middle'
Label:
id: lastW_lbl
text: 'Last Watering: '
font_size: 24
halign: 'center'
valign: 'middle'
Label:
id: lastW_val
text: root.last_water
font_size: 24
halign: 'center'
valign: 'middle'
Label:
id: nextW_lbl
text: 'Time before Next Watering: '
font_size: 24
halign: 'center'
valign: 'middle'
Label:
id: nextW_val
text: root.time_text
font_size: 24
halign: 'center'
valign: 'middle'
"""
Builder.load_string(kv)
# create the left screen
class LeftScreen(Screen):
def __init__(self, **kwargs):
super(LeftScreen, self).__init__(**kwargs)
self.temp = dc(temperature)
self.hum = dc(humidity)
self.last_water = dc(last_water)
self.time_next = dc(time_next)
def reload(self,value):
self.ids.lastU.text='Last Update: '+time.strftime("%H:%M:%S")
self.ids.temp_val.text=temperature
self.ids.hum_val.text=humidity
self.ids.lastW_val.text=last_water
self.ids.nextW_val.text=time_next
class RightScreen(Screen):
def __init__(self,**kwargs):
super(RightScreen,self).__init__(**kwargs)
self.layout = GridLayout()
self.add_widget(self.layout)
class SmartGardener(App):
def build(self):
sm = ScreenManager()
ls = LeftScreen(name='data')
sm.add_widget(ls)
sm.current = 'data'
return sm
def reset():
import kivy.core.window as window
from kivy.base import EventLoop
if not EventLoop.event_listeners:
from kivy.cache import Cache
window.Window = window.core_select_lib('window', \
window.window_impl, True)
Cache.print_usage()
for cat in Cache._categories:
Cache._objects[cat] = {}
myApp = SmartGardener()
if __name__ == '__main__':
reset()
myApp.run()
Is the error with the image that I inserted or the variables I used for the labels? I want to insert the image as the background of the UI.
Also, there seems to be some error with the variable 'time_next' when I tried to accessing it from the kivy file. What is the right way to access the attribute 'time_next' of object MainScreen in the kv quote?
Okay, i tried to run your code and here is what i found:
you try to access 'time_text' in kv file, while you set in the class 'time_next', that's a typo but even after i fixed it i had to set defaults in the kv file for all the variables that you call, hum, temp, time_next, last_water:
<LeftScreen>:
time_text: ''
last_water:''
hum: ''
temp: ''
GridLayout:
cols: 2
...
next you use the time.striftime which is a typo to time.strftime, yet you need to import it in the kv code like so:
:import strftime time.strftime
<LeftScreen>:
...
and use it like:
Label:
id: lastU
text: '[i]'+'Last Update: '+strftime("%H:%M:%S")+'[/i]'
see the kv language docs for it: under special syntax
i wasn't able to run your code yet, i didn't have the Fonts you used, so i simply commented those lines, and once it ran i noticed that the Label's show the markup, to use it you need to explicitly set markupe=True
Label:
id: title
text: '[b][i]Smart[/i]'+' Gardener[/b]'
markup: True
color: (0.25,0.5,0.1,1)
font_size: 60
#font_name: 'times'
Label:
id: group
text: '[i]group 8[/i]'
markup: True
color: (0.3,0.3,0.6,1)
font_size: 45
#font_name: 'Arial'
valign: 'bottom'
At last, clicking the refresh button calls reload without any value, while it expects some value, so the 'refresh' button would raise a TypeError.

Categories

Resources