Kivy Sidebar plus content layout - python

I want a fixed width right sidebar on my kivy app with a list of buttons and a main area where to draw things, I am not sure which is the right way to go about it (i.e. which layout), here's where I am at so far:
layoutApp.py...
from kivy.app import App
class layoutApp(App):
pass
if __name__ == '__main__':
layoutApp().run()
And layoutApp.kv...
BoxLayout:
orientation: 'vertical'
BoxLayout:
Button:
size_hint_x: 2
BoxLayout:
orientation: 'vertical'
size_hint_x: 0.5
Button:
Button:
Button:
Button:
Which produces:
The issue is that sizes are relative, i.e. the right sidebar width changes depending on screen seize/resize which is not the intended behavior.
Thanks !

You can set the width of the sidebar, and then have the large button width depend on that by using ids:
BoxLayout:
id: top_box
orientation: 'vertical'
BoxLayout:
Button:
size_hint_x: None
width: top_box.width - bottom_box.width
BoxLayout:
id: bottom_box
orientation: 'vertical'
size_hint_x: None
width: 150
Button:
Button:
Button:
Button:

Slight modifications to #John_Anderson with skinny top aligned buttons:
BoxLayout:
id: top_box
orientation: 'vertical'
BoxLayout:
Button:
size_hint_x: None
width: top_box.width - bottom_box.width
BoxLayout:
padding: 4
id: bottom_box
orientation: 'vertical'
size_hint_x: None
width: 200
spacing: 2
Button:
id: button_1
background_normal: ''
background_color: .2, .2, .2, 1
text: 'Button 1'
color: .6, .6, .6, 1
size_hint_x: None
size_hint_y: None
width: 192
height: 40
Button:
id: button_2
background_normal: ''
background_color: .2, .2, .2, 1
text: 'Button 2'
color: .6, .6, .6, 1
size_hint_x: None
size_hint_y: None
width: 192
height: 40
Button:
id: button_3
background_normal: ''
background_color: .2, .2, .2, 1
text: 'Button 3'
color: .6, .6, .6, 1
size_hint_x: None
size_hint_y: None
width: 192
height: 40
Button:
id: button_4
background_normal: ''
background_color: .2, .2, .2, 1
text: 'Button 4'
color: .6, .6, .6, 1
size_hint_x: None
size_hint_y: None
width: 192
height: 40
Widget:
Results in:

Related

Kivy kv creating toolbar with active buttons which change window when pressed

Basically I've created a toolbar with two widgets. One widget (account) should change to a new window when pressed. The other (menu) should open three buttons when it is pressed. When you press on of the three buttons it should also change to a new window.
I don't know how to implement that...
Can anyone help me?
Here's my code:
kv = """
<MenuScreen>:
name: 'mainmenu'
canvas.before:
Rectangle:
pos: self.pos
size: self.size
source: 'background.jpg'
Screen:
BoxLayout:
orientation: 'vertical'
MDTopAppBar:
title: 'Fitness App'
left_action_items: [["menu", lambda x: app.navigation_draw()]]
right_action_items: [["account", lambda x: app.callback()]]
elevation:5
MDLabel:
text: 'hello world'
halign: 'center'
BoxLayout:
spacing: 1
orientation: "vertical"
Label:
text: "Welcome back"
font_size: 100
color : 0,0,0,1
Button:
text: 'Get Started'
font_size:100
color: 0, 0, 1, 1
background_color: 0, 0, 0, 1
size_hint: 1, 1
pos_hint: {"x":0, "top":1}
on_release:
root.manager.current = 'screen2'
root.manager.transition.direction = "left"
Button:
text: 'Leave App'
font_size: 100
color: 0, 0, 1, 1
background_color: 0, 0, 0, 1
size_hint: 1, 1
pos_hint: {"x":0, "top":0}
on_release: root.manager.current = app.exit_software()
<Screen2>:
name: 'screen2'
canvas.before:
Rectangle:
pos: self.pos
size: self.size
source: 'background.jpg'
BoxLayout:
spacing: 1
orientation: "vertical"
ScrollView:
id: scroll_view
always_overscroll: False
BoxLayout:
size_hint_y: None
height: self.minimum_height
orientation: 'vertical'
Label:
id: label
text: "Please choose your problem Area"
color : 0,0,0,1
size_hint: None, None
pos_hint: {"x":0, "top":1}
font_size: 50
size: self.texture_size
Button:
text: 'Shoulders'
font_size: 30
color : 0,0,1,1
on_release:
root.manager.current = 'shoulders'
root.manager.transition.direction = "left"
Button:
text: 'Knees'
font_size: 30
color : 0,0,1,1
background_color: 0, 0, 0, 1
size_hint_y: 1
on_release:
root.manager.current = 'knees'
root.manager.transition.direction = "left"
Button:
text: 'Back'
font_size: 30
color : 0,0,1,1
background_color: 0, 0, 0, 1
size_hint_y: 1
on_release:
root.manager.current = 'back'
root.manager.transition.direction = "left"
Button:
text: 'Back to main menu'
font_size: 30
color : 0,0,1,1
background_color: 0, 0, 0, 1
size_hint_y: 1
on_release:
root.manager.current = 'mainmenu'
root.manager.transition.direction = "right"
<Screen_shoulders>:
name: 'shoulders'
canvas.before:
Rectangle:
pos: self.pos
size: self.size
source: 'shoulders.png'
BoxLayout:
spacing: 1
orientation: "vertical"
ScrollView:
id: scroll_view
always_overscroll: False
BoxLayout:
size_hint_y: None
height: self.minimum_height
orientation: 'vertical'
Label:
id: label
text: "Choose an activity"
font_size: 50
color : 0,0,0,1
size: self.texture_size
Button:
text: 'Activity1'
font_size: 50
color : 0,0,0,1
size_hint_y: 0.3
on_release:
root.manager.current = 'shouldersActivity1'
root.manager.transition.direction = "right"
Button:
text: 'Activity2'
font_size: 50
color : 0,0,0,1
size_hint_y: 0.3
on_release: app.add_text()
Button:
text: 'Back to main menu'
font_size: 20
color : 0,0,0,1
size_hint_y: 0.1
on_release:
root.manager.current = 'screen2'
root.manager.transition.direction = "right"
ScreenManager:
id: screen_manager
MenuScreen:
id: menu_scr
Screen2:
id: scr_2
"""
class MenuScreen(Screen):
pass
class Screen2(Screen):
pass
class AddTextApp(MDApp):
def __init__(self, **kwargs):
super().__init__(**kwargs)
def build(self):
return Builder.load_string(kv)
def add_text(self):
self.root.ids.scr_2.ids.label.text += f"Some new Text\n"
self.root.ids.scr_2.ids.scroll_view.scroll_y = 0
def callback(self, instance_action_top_appbar_button):
print(instance_action_top_appbar_button)
#staticmethod
def exit_software():
App.get_running_app().stop()
def navigation_draw(self):
# open new window
def callback(self):
# open new window
if __name__ == '__main__':
AddTextApp().run()
I don't know how to make the widgets change window when they're pressed.

ScrollView not Scrolling with GridLayout

I Have browsed the web for 30 minutes looking for a solution for this problem but none of the examples on the web worked. I have tried custom heights in the GridLayout and played around with various values that other people used in the web but none of them worked. I also tried to run the code of the ScrollView in another file with only this code but the scrolling still didn't work.
The .py file is not relevant here i think because i have no code in there for this section of my program. If you still need it or need more of my kv file i will post it just send me a message thank you :)
kv:
<TrainingPlans>
name: "trainingplans"
ScrollView:
size_hint_y: .85
pos_hint: {"x": 0, "y": .15}
do_scroll_x: False
do_scroll_y: True
GridLayout:
size: (root.width, root.height)
size_hint_x: None
size_hint_Y: None
cols: 2
height: self.minimum_height
row_default_height: 150
row_force_default: True
Label:
text: "training1"
Button:
size_hint: .3, 1
background_normal: "training_programs/unknown.jpeg"
Label:
text: "training2"
Button:
size_hint: .3, 1
background_normal: "training_programs/unknown.jpeg"
Label:
text: "training3"
Button:
size_hint: .3, 1
background_normal: "training_programs/unknown.jpeg"
Label:
text: "training4"
Button:
size_hint: .3, 1
background_normal: "training_programs/unknown.jpeg"
Label:
text: "training5"
Button:
size_hint: .3, 1
background_normal: "training_programs/unknown.jpeg"
Label:
text: "training6"
Button:
size_hint: .3, 1
background_normal: "training_programs/unknown.jpeg"
Label:
text: "training7"
Button:
size_hint: .3, 1
background_normal: "training_programs/unknown.jpeg"
Label:
text: "training8"
Button:
size_hint: .3, 1
background_normal: "training_programs/unknown.jpeg"
Label:
text: "training9"
Button:
size_hint: .3, 1
background_normal: "training_programs/unknown.jpeg"
FloatLayout:
size_hint: 1, .15
Button:
text: "Back"
size_hint: .3, .8
pos_hint: {"x": .01, "y": .06}
on_release:
app.root.current = "mainwindow"
root.manager.transition.direction = "right"
Just a typo. Change:
size_hint_Y: None
to
size_hint_y: None
in your GridLayout rule in the kv.

Kivy/KivyMD Screen takes 10 seconds to load on Android, 3 seconds on Windows

We are developing an app with many screens and much kv code, using lazy loading template by Kulothungan on GitHub and it is fine, besides one screen, the calculator. It takes 10 seconds or more to load on Android, and we don't understand why!
Part of code:
# ----- Python Class: -----
class CustomRoundButton(ButtonBehavior, CircularRippleBehavior, CircularElevationBehavior, MDFloatLayout):
pass
# ----- KV Class: -----
<Calculator>
name: "calculator"
MDBoxLayout:
padding: "35dp"
spacing: "25dp"
orientation: "vertical"
MDLabel:
id: calclabel
text: "0"
halign: "right"
valign: "center"
font_style: "H2"
size_hint_y: .4
pos_hint_y: .5
GridLayout:
cols: 4
spacing: "15dp"
CustomRoundButton:
pos_hint: {"center_x": .5, "center_y": .5}
radius: lbl.texture_size[0] + self.height / 2
md_bg_color: app.theme_cls.accent_color
size_hint_y: None
height: self.width
elevation: 8
on_release:
root.calcformula = ""
calclabel.text = "0"
Label:
id: lbl
text: "AC"
font_size: root.height / 20
-text_size: None, None
size_hint: None, None
size: self.texture_size[0] + dp(50), self.texture_size[0] + dp(50)
pos_hint: {"center_x": .5, "center_y": .5}
color: 1, 1, 1, 1
...
Here is a link to the whole screen code
Any help would be really appreciated!
Thanks!

Horizontal and vertical scrollview on same screen kivy

I'm trying to create a screen which has a horizontal scrollview at the top of the page, taking up ~25% of the vertical space and a vertical scrollview taking up the rest of the space (and then being able to scroll further down the screen).
I've managed to create a horizontal scrollview but can't get the vertical scrollview to work on the same screen.
py file:
import kivy
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.lang import Builder
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.image import Image
from
Window.clearcolor = (1,1,1,1)
class Window(Screen):
pass
class MyApp(App):
theme_cls = ThemeManager()
def build(self):
kv = Builder.load_file("kivy.kv")
self.sm = WindowManager()
screens = [Window(name="window")]
for screen in screens:
self.sm.add_widget(screen)
self.sm.current = "window"
return self.sm
if __name__ == '__main__':
MyApp().run()
kv file:
<Window>:
name: "window"
NavigationLayout:
id: nav_layout
MyNavDrawer:
BoxLayout:
orientation: "vertical"
MDToolbar:
pos_hint: {'top': 1}
md_bg_color: 1, 1, 1, 1
ScrollView: #horizontal scrollview - works fine
size_hint_y: 0.5
GridLayout:
rows: 1
id: scroll_horizontal
size_hint_x: None
col_default_width: root.width*0.2
width: self.minimum_width*1.3
spacing: 20
ScrollView: #vertical scrollview, not working
size_hint_y: 0.85
do_scroll_x: False
GridLayout:
id: scroll_vertical
cols: 1
size_hint_y: None
spacing: 40
height: self.minimum_height
canvas:
Color:
rgba: (1, 1, 1, 1)
Rectangle:
size: self.size
pos: self.pos
BoxLayout:
cols: 2
spacing: 10
Button:
size_hint_y: 0.5
text: "Btn1"
Button:
size_hint_y: 0.5
text: "Btn2"
BoxLayout:
cols: 2
spacing: 10
Button:
size_hint_y: 0.5
text: "Btn1"
Button:
size_hint_y: 0.5
text: "Btn2"
BoxLayout:
cols: 2
spacing: 10
Button:
size_hint_y: 0.5
text: "Btn1"
Button:
size_hint_y: 0.5
text: "Btn2"
I'd like them to be independent of each other, so you can either scroll horizontal on the top scrollview or scroll veritcally through the buttons on the boxlayouts on the vertical scrollview
It took some work to get your MCVE working, but here is the part of your kv that I modified to get scrolling working in both directions with two ScrollViews:
ScrollView: #horizontal
size_hint_y: 0.25
do_scroll_y: False
GridLayout:
rows: 1
id: scroll_horizontal
size_hint: None, 1
col_default_width: root.width*0.2
width: self.minimum_width*1.3
spacing: 20
BoxLayout:
cols: 2
spacing: 10
size_hint_x: None
width: self.minimum_width
Button:
size_hint: None, 1
width: 500
text: "Btn1"
Button:
size_hint: None, 1
width: 500
text: "Btn2"
BoxLayout:
cols: 2
spacing: 10
size_hint_x: None
width: self.minimum_width
Button:
size_hint: None, 1
width: 500
text: "Btn1"
Button:
size_hint: None, 1
width: 500
text: "Btn2"
BoxLayout:
cols: 2
spacing: 10
size_hint_x: None
width: self.minimum_width
Button:
size_hint: None, 1
width: 500
text: "Btn1"
Button:
size_hint: None, 1
width: 500
text: "Btn2"
ScrollView: # vertical
size_hint_y: 0.75
do_scroll_x: False
GridLayout:
id: scroll_vertical
cols: 1
size_hint: 1.0, None
spacing: 40
# must set height
height: self.minimum_height
BoxLayout:
cols: 2
spacing: 10
size_hint_y: None
Button:
size_hint: 0.5, None
height: 100
text: "Btn1"
Button:
size_hint: 0.5, None
height: 100
text: "Btn2"
BoxLayout:
cols: 2
spacing: 10
size_hint_y: None
height: self.minimum_height
Button:
size_hint: 0.5, None
height: 100
text: "Btn1"
Button:
size_hint: 0.5, None
height: 100
text: "Btn2"
BoxLayout:
cols: 2
spacing: 10
size_hint_y: None
height: self.minimum_height
Button:
size_hint: 0.5, None
height: 100
text: "Btn1"
Button:
size_hint: 0.5, None
height: 100
text: "Btn2"

Widgets inside Tabbed Panel in Kivy

I'm new to designing in kivy and I'm trying to display a listview, inputbox and label inside a Tab panel but it's showing empty panel. I'm not sure where is my mistake.
I want to do a simple search of users by just typing the username in the inputbox then the listview will automatically update the records inside the listview.
I'm using kivy 1.10.0 and python 3.6
Here is my code in kivy file:
<AdminMainScreen#Screen>:#===================MAIN SCREEN=========================
txt_search: txt_search
view_user_list: view_user_list
BoxLayout:
size_hint_y: 1
size_hint_x: 1
canvas:
Color:
rgb: .132, .232, .249
Rectangle:
size: self.size
TabbedPanel:
do_default_tab: False
TabbedPanelItem:
text:"1st Tab"
Label:
text: "Content of Admin Panel"
TabbedPanelItem:
text:"2nd Tab"
Label:
text: "Content of Second Panel"
TabbedPanelItem:
text:"Manage Users"
BoxLayout:
size_hint_y: .2
size_hint_x: 1
orientation: 'horizontal'
Label:
text: "Search User"
size_hint_x: .25
spacing: .2, .2
TextInput:
id: txt_search
text: ""
size_hint_x: .3
spacing: .2, .2
Label:
id: lbl_search
size_hint_y:None
height: 10
text: ""
ListView:
color: [0,0,0]
id: view_user_list
size_hint_x: 1
size_hint_y: .8
item_strings: []
adapters:
ListAdapter(data=[], cls = ListItemButton)
I don't think that having multiple widgets in a TabbedPanelItem is allowed, there is only one child - content. So just put an extra Layout and everything you want in the tab inside that one layout:
BoxLayout: # The only child of panel item
size_hint_y: 1
size_hint_x: 1
orientation: 'horizontal'
BoxLayout:
size_hint_y: 0.2
size_hint_x: 1
orientation: 'horizontal'
Label:
text: "Search User"
size_hint_x: .25
spacing: .2, .2
TextInput:
id: txt_searh
text: ""
size_hint_x: .3
spacing: .2, .2
Label:
id: lbl_search
size_hint_y:None
...

Categories