Can't change location of widgets in KivyMD - python

I'm trying to move MDLabel and MDRectangleFlatButton to the center of the screen, but both pos_hint and halign are getting ignored.
app.kv:
ScreenManager:
MainScreen:
<MainScreen>
name: 'main_screen'
BoxLayout:
orientation: 'vertical'
MDToolbar:
title: 'My App'
MDLabel:
text: 'Welcome again!'
pos_hint: {'center_x': 0.5, 'center_y': 0.5}
style: 'H5'
MDRectangleFlatButton:
text: 'Enter'
pos_hint: {'center_x': 0.5, 'center_y': 0.5}
app.py:
from kivymd.app import MDApp
from kivy.lang import Builder
from kivy.uix.screenmanager import Screen, ScreenManager
class MainScreen(Screen):
pass
sm = ScreenManager()
sm.add_widget(MainScreen(name="main_screen"))
class MyApp(MDApp):
def build(self):
return Builder.load_file("app.kv")
MyApp().run()

Related

How to manipulate images and such in kivyMD

I wrote this code but now i don't know how to manipulate my images so I am stuck i need help on how to
add images if i have multiple screens
and how to also add other labels so basically screen manipulation with multiple screens
from kivymd.app import MDApp
from kivy.lang.builder import Builder
from kivy.uix.screenmanager import Screen, ScreenManager
screen_helper = """
ScreenManager:
MenuScreen:
ProfileScreen:
<MenuScreen>:
name: "menu"
MDRectangleFlatButton:
text: 'Profile'
pos_hint: {'center_x':0.5, 'center_y':0.5}
on_press: root.manager.current = 'profile'
<ProfileScreen>:
name: 'profile'
MDLabel:
text: 'Welcome Nate'
halign: 'center'
MDRectangleFlatButton:
text: 'Back'
pos_hint: {'center_x':0.5, 'center_y':0.2}
on_press: root.manager.current = 'menu'
"""
class MenuScreen(Screen):
pass
class ProfileScreen(Screen):
pass
sm = ScreenManager()
sm.add_widget(MenuScreen(name='menu'))
sm.add_widget(ProfileScreen(name='profile'))
class DemoApp(MDApp):
def build(self):
screen = Builder.load_string(screen_helper)
return screen
DemoApp().run()
You can use Image to put image
<ProfileScreen>:
name: 'profile'
Image:
source: '/home/furas/test/lenna.png'
MDLabel:
text: 'Welcome Nate'
halign: 'center'
MDRectangleFlatButton:
text: 'Back'
pos_hint: {'center_x':0.5, 'center_y':0.2}
on_press: root.manager.current = 'menu'
Result:
Original image from Wikipedia: Lenna
EDIT:
Full code
from kivymd.app import MDApp
from kivy.lang.builder import Builder
from kivy.uix.screenmanager import Screen, ScreenManager
screen_helper = """
ScreenManager:
MenuScreen:
ProfileScreen:
<MenuScreen>:
name: "menu"
Image:
source: '/home/furas/test/lenna.png'
MDRectangleFlatButton:
text: 'Profile'
pos_hint: {'center_x':0.5, 'center_y':0.5}
on_press: root.manager.current = 'profile'
<ProfileScreen>:
name: 'profile'
Image:
source: '/home/furas/test/lenna.png'
MDLabel:
text: 'Welcome Nate'
halign: 'center'
color: (0, 0, 0)
MDRectangleFlatButton:
text: 'Back'
pos_hint: {'center_x':0.5, 'center_y':0.2}
on_press: root.manager.current = 'menu'
"""
class MenuScreen(Screen):
pass
class ProfileScreen(Screen):
pass
sm = ScreenManager()
sm.add_widget(MenuScreen(name='menu'))
sm.add_widget(ProfileScreen(name='profile'))
class DemoApp(MDApp):
def build(self):
screen = Builder.load_string(screen_helper)
return screen
DemoApp().run()

How use BoxLayout from KivyMD

Why can I move the button only horizontally using the vertical orientation of BoxLayout, and only vertically using the horizontal orientation? For example:
from kivy.lang import Builder
from kivymd.app import MDApp
KV = '''
Screen:
BoxLayout:
orientation: 'vertical'
MDRaisedButton:
pos_hint: {'center_x': .3,'center_y': .5}
'''
class Test(MDApp):
def build(self):
return Builder.load_string(KV)
Test().run()
Horizontal orientation, also the default orientation:
from kivy.lang import Builder
from kivymd.app import MDApp
KV = '''
Screen:
BoxLayout:
orientation: 'horizontal'
MDRaisedButton:
pos_hint: {'center_x': .3,'center_y': .5}
'''
class FindWord(MDApp):
def build(self):
return Builder.load_string(KV)
FindWord().run()
How to move widgets freely on both axes? Help please
from kivy.lang import Builder
from kivymd.app import MDApp
KV = '''
MDScreen:
MDBoxLayout:
adaptive_size: True
pos_hint: {'center_x': .3, 'center_y': .5}
MDRaisedButton:
text: "MDRaisedButton"
'''
class FindWord(MDApp):
def build(self):
return Builder.load_string(KV)
FindWord().run()
https://kivy.org/doc/stable/api-kivy.uix.floatlayout.html
https://kivy.org/doc/stable/api-kivy.uix.boxlayout.html

MDExpansion Panel - kivy.properties.DictProperty' object has no attribute 'panel_container'

I am currently building a mobile app with kivy. In one of my screens I am trying to include an MDExpansionPanel, although I have tried with a lot of different codes, and searched on the web for solutions, either I get an error, or simply the Expansion Panel is not rendered in my screen. I am using ScreenManager since I have 5 screens, with the possibility of increasing such number.
The relevant Python code is the following:
from kivy.app import App
from kivy.properties import ObjectProperty
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.screenmanager import ScreenManager, Screen
from kivymd.app import MDApp
from kivymd.theming import ThemeManager
from kivymd.toast import toast
from kivymd.uix.picker import MDDatePicker, MDTimePicker
from kivymd.uix.expansionpanel import MDExpansionPanel
from kivymd.uix.boxlayout import MDBoxLayout
class LoginWindow(Screen):
pass
class CreateAccountWindow(Screen):
pass
class MainWindow(Screen):
pass
class TravelManagerWindow(Screen):
pass
class IngActivWindow(Screen):
panel_container = ObjectProperty(None)
def on_pre_enter(self, *args):
self.add_panels()
def show_timepicker(self):
picker = MDTimePicker()
picker.bind(time=self.got_time)
picker.open()
def got_time(self, picker_widget, time):
self.text = str(time.hour) + ":" + str(time.minute)
self.focus = False
# selectedTime= self.text
print(self.text)
self.ids.tiempoActiv.text = self.text
def add_panels(self):
for i in range(5):
IngActivWindow.ids.panel_container.add_widget(
MDExpansionPanel(
icon="actividades.png",
content=MyContent(),
panel_cls=MDExpansionPanelOneLine(
text="Text",
)
)
)
class MyContent(MDBoxLayout):
pass
class WindowManager(ScreenManager):
ScreenManager().add_widget(LoginWindow(name='login'))
ScreenManager().add_widget(CreateAccountWindow(name='create'))
ScreenManager().add_widget(MainWindow(name='main'))
ScreenManager().add_widget(IngActivWindow(name='ingActiv'))
ScreenManager().add_widget(TravelManagerWindow(name='travelManager'))
class powerApp1(MDApp):
def build(self):
self.theme_cls.primary_palette = "Teal"
return WindowManager()
if __name__ == "__main__":
powerApp1().run()
The relevant kv code is the following:
(I have an image on the background and an Action Bar before the MDBoxLayout where I am trying to add the Expansion Panel)
<WindowManager>:
LoginWindow:
CreateAccountWindow:
MainWindow:
IngActivWindow:
TravelManagerWindow:
<IngActivWindow>:
name: 'ingActiv'
panel_container: panel_container
FloatLayout:
cols:1
canvas.before:
Rectangle:
pos: self.pos
size: self.size
source: 'ingActiv_background.png'
ActionBar:
pos_hint: {'top':1}
ActionView:
use_separator: True
ActionPrevious:
title: '---------'
with_previous: False
ActionButton:
icon: 'homeIcon.png'
on_press:
root.manager.current = 'main'
root.manager.transition.direction = 'right'
ActionGroup:
text: 'Gastos de Viaje'
mode: 'spinner'
size_hint:(None,None)
size: root.width/5,root.height/12
ActionButton:
text: 'Solicitar'
on_release:
root.manager.current = 'solicitud'
root.manager.transition.direction = 'left'
ActionButton:
text: 'Comprobar'
on_release:
root.manager.current = 'comprobar'
root.manager.transition.direction = 'left'
ActionGroup:
text: 'Opciones'
mode: 'spinner'
size_hint:(None,None)
size: root.width/5,root.height/12
ActionButton:
text: 'Ingresar Actividad'
on_release:
root.manager.current = 'ingActiv'
root.manager.transition.direction = 'left'
ActionButton:
text: 'Enviar Reporte'
ActionButton:
text: 'Cerrar Sesion'
on_release:
root.manager.current = 'login'
root.manager.transition.direction = 'down'
MDBoxLayout:
cols:1
size_hint: 1,0.6
pos_hint: {"center_x": 0.5, "center_y": 0.5}
ScrollView:
GridLayout:
id: panel_container
cols: 1
pos_hint: {"center_x": 0.5, "center_y": 0.5}
<MyContent>:
size_hint: 1, None
height: self.minimum_height
orientation: 'horizontal'
Button:
size_hint: None, None
Thanks a lot in advance for your support,
Have a great day.

how to bind two or more events with on_text_validate

I want that on pressing enter in a TextInput widget it should do two things-
change the screen (i am using screen manager)
and search for the keyword
I do know that with on_text_validate we can perform either of the tasks by-
1.root.manager.current='namesomething'
2.root.function_which_has_search_algorithm()
is there anyway with which i can do both the things(changing_the_screen,calling_the_search_function) using on_text_validate or do i have to use some other technique?
here a sample code:
import kivy
kivy.require("1.10.0")
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager,Screen
from kivy.lang import Builder
Builder.load_file('screenswitch.kv')
class MainScreen(Screen):
def SelectWord(self):
''' some search
code'''
class OtherScreen(Screen):
pass
sm = ScreenManager()
sm.add_widget(MainScreen(name='main'))
sm.add_widget(OtherScreen(name='other'))
class ScreenSwitchApp(App):
def build(self):
return sm
obj = ScreenSwitchApp()
obj.run()
heres my kivy code:
<MainScreen>:
BoxLayout:
TextInput:
text: "Search your word here"
color: 1,1,1,1
id: search_input
width: 200
size_hint: None, .20
pos_hint: {"center_x": .5, "center_y": 0.5}
multiline: False
on_text_validate: root.SelectWord() # i want this to change screen also
<OtherScreen>:
BoxLayout:
Button:
text: 'back to main screen'
on_press: root.manager.current='main'
A possible solution is to create a new function that calls that 2 functions:
*.py
import kivy
kivy.require("1.10.0")
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager,Screen
from kivy.lang import Builder
Builder.load_file('screenswitch.kv')
class MainScreen(Screen):
def some_function(self):
self.SelectWord()
self.manager.current='other'
def SelectWord(self):
print("SelectWord")
class OtherScreen(Screen):
pass
sm = ScreenManager()
sm.add_widget(MainScreen(name='main'))
sm.add_widget(OtherScreen(name='other'))
class ScreenSwitchApp(App):
def build(self):
return sm
obj = ScreenSwitchApp()
obj.run()
*.kv
<MainScreen>:
BoxLayout:
TextInput:
text: "Search your word here"
color: 1,1,1,1
id: search_input
width: 200
size_hint: None, .20
pos_hint: {"center_x": .5, "center_y": 0.5}
multiline: False
on_text_validate: root.some_function() # i want this to change screen also
<OtherScreen>:
BoxLayout:
Button:
text: 'back to main screen'
on_press: root.manager.current='main'
TextInput:
id:qty_inp
size_hint_x:.1
multiline:False
on_text_validate:root.update_price()
on_text_validate:root.update_purchase
Like the above code you can add one more on_text_validate: root.method()

ListView in Kivy (.kv vs .py)

If I initialize an empty ListView in a .kv file,
<Panel>:
do_default_tab: False
size_hint_y: 0.7
TabbedPanelItem:
id: tab_1
text: 'VIEW'
ListView:
id: VIEWlist
adapter:
ListAdapter(
data=[],
args_converter = root.args_converter,
selection_mode='multiple',
cls=ListItemButton
)
how would I add data to it from the .py side?
You need to access VIEWlist.adapter.data property. An example:
from kivy.app import App
from kivy.uix.tabbedpanel import TabbedPanel
from kivy.lang import Builder
Builder.load_string('''
#:import ListItemButton kivy.uix.listview.ListItemButton
#:import ListAdapter kivy.adapters.listadapter.ListAdapter
<Panel>:
size_hint: .5, .5
pos_hint: {'center_x': .5, 'center_y': .5}
do_default_tab: False
TabbedPanelItem:
id: tab_1
text: 'VIEW'
BoxLayout:
orientation: 'vertical'
Button:
text: 'add'
on_press: root.add()
ListView:
id: VIEWlist
adapter:
ListAdapter(
data=[],
selection_mode='multiple',
cls=ListItemButton)
''')
class Panel(TabbedPanel):
def add(self, *args):
self.ids['VIEWlist'].adapter.data.append('txt')
class TabbedPanelApp(App):
def build(self):
return Panel()
if __name__ == '__main__':
TabbedPanelApp().run()

Categories

Resources