Widgets inside Tabbed Panel in Kivy - python

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
...

Related

How do I align text inside a kivy label within a .kv file?

I try to make a gui for a text based RPG, and now I want to align the text of some labels to the top left, but "halign:" and "valign:" don't seem to do anything.
So how do I align the text inside my labels? Is there something I have done horribly wrong?
This is how the GUI looks at this moment and I marked where the text should be with green arrows:
This is how my .kv file looks:
BoxLayoutExample:
<BackgroundColor#Widget>:
background_color: 1,1,1,1
canvas.before:
Color:
rgba: root.background_color
Rectangle:
size: self.size
pos: self.pos
<BackgroundLabel#Label+BackgroundColor>:
background_color: 0, 0, 0, 0
<BoxLayoutExample>:
orientation: "vertical"
BoxLayout:
orientation:"horizontal"
BackgroundLabel:
background_color: 1,0,0,1
text: "Placeholder Text\nTEST\nTEST\nTEST\nTEST\nTEST\nTEST\nTEST\nTEST\nTEST\nTEST\nTEST\nTEST\nTEST"
halign: "left"
valign: "top"
font_size: "10sp"
size_hint: .5, 1
Label:
text: "Placeholder Map/Enemy #TEST TEST TEST TEST TEST \nTEST\nTEST\nTEST\nTEST\nTEST\nTEST\nTEST\nTEST\nTEST\nTEST\nTEST\nTEST\nTEST"
halign: "left"
valign: "top"
size_hint: 1, 1.3
BoxLayout:
orientation:"vertical"
size_hint: .5, 1
Label:
background_color: 1,1,1,.5
text: "Placeholder Stats\nHP\nMP\nDMG\nXP\nLVL"
halign: "left"
valign: "top"
size_hint: 1, .3
ScrollView:
size_hint: 1, .7
scroll_distance: 100
Label:
text: "Placeholder Inventory\nTEST\nTEST\nTEST\nTEST\nTEST\nTEST\nTEST\nTEST\nTEST\nTEST\nTEST\nTEST\nTEST\nTEST\nTEST\nTEST\nTEST\nTEST\nTEST\nTEST\nTEST\nTEST\nTEST\nTEST\nTEST\nTEST\nTEST\nTEST\nTEST\nTEST\nTEST\nTEST\nTEST\nTEST\nTEST\nTEST\nTEST\nTEST\nTEST"
size_hint: None, None
size: self.texture_size
halign: "left"
valign: "top"
BoxLayout:
orientation: "horizontal"
size: "60dp","60dp"
size_hint: None,None
Label:
size: "60dp","60dp"
size_hint: None,None
Button:
text: "go\nnorth"
size: "60dp","60dp"
size_hint: None,None
Label:
size: "60dp","60dp"
size_hint: None,None
BoxLayout:
orientation: "horizontal"
size: "180dp","60dp"
#pos: "0dp","60dp"
size_hint: None,None
Button:
text: "go\nwest"
size: "60dp","60dp"
#pos: "0dp","60dp"
size_hint: None,None
pos_hint: {"x":0}
Button:
text: "go\nsouth"
size: "60dp","60dp"
size_hint: None,None
Button:
text: "go\neast"
size: "60dp","60dp"
#pos: "0dp","60dp"
size_hint: None,None
Label:
size: "60dp","60dp"
size_hint: None,None
Button:
text: "use\nitem"
size: "60dp","60dp"
size_hint: None,None
Button:
text: "equip\ngear"
size: "60dp","60dp"
size_hint: None,None
Button:
text: "unequip\ngear"
size: "60dp","60dp"
size_hint: None,None
Thanks for your help, I really appreciate it.
You need to add this argument in your label:
text_size: self.size
Then the halign and valign arguments will work properly, for example:
Label:
text: "Placeholder Map/Enemy #TEST TEST TEST TEST TEST \nTEST\nTEST\nTEST\nTEST\nTEST\nTEST\nTEST\nTEST\nTEST\nTEST\nTEST\nTEST\nTEST"
text_size: self.size
halign: "left"
valign: "top"
size_hint: 1, 1.3
More details in the official kivy documentation.

Kivy Sidebar plus content layout

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:

Cycling though popup windows in Kivy

I created a main windows with 6 toggle buttons in Kivy.
I like to access a popup window with related settings via a long-press event on each of these toggle buttons.
The popup window is defined and has "next" and "previous" buttons to cycle from one settings page to the next one.
How can I avoid to create each of these popup definitions manually in Kivy?
Dummy .kv code:
#:import Factory kivy.factory.Factory
<MyPopup2#Popup>:
auto_dismiss: False
title: "Popup Window No. 2"
Button:
text: 'Close me, too!'
on_release: root.dismiss()
MyPopup1#Popup:
auto_dismiss: False
size_hint: None,None
size: 400,300
title: "Popup Window No. 1"
BoxLayout:
orientation: "vertical"
BoxLayout:
orientation: "vertical"
BoxLayout:
Label:
text: 'Circuit Active:'
Switch:
id: "switch1"
BoxLayout:
Label:
text: 'Default Watering Time: [min]'
TextInput:
text: '30'
BoxLayout:
Label:
text: 'Watering Group'
TextInput:
text: '3'
BoxLayout:
Button:
text: 'Previous'
Button:
text: 'Cancel'
on_release: root.dismiss()
Button:
text: 'Save + Exit'
Button:
text: 'Next'
on_release: root.dismiss()
on_release: Factory.MyPopup2().open()
BoxLayout:
orientation: "vertical"
padding: 5
BoxLayout:
BoxLayout:
padding: 5
ToggleButton:
text: "Wasserkreis 1"
# disabled: True
on_release: Factory.MyPopup1().open()
BoxLayout:
padding: 5
ToggleButton:
text: "Wasserkreis 2"
BoxLayout:
padding: 5
ToggleButton:
text: "Wasserkreis 3"
BoxLayout:
BoxLayout:
padding: 5
ToggleButton:
text: "Wasserkreis 4"
BoxLayout:
padding: 5
ToggleButton:
text: "Wasserkreis 5"
BoxLayout:
padding: 5
ToggleButton:
text: "Wasserkreis 6"
BoxLayout:
BoxLayout:
padding: 5
Label:
text: 'Drei Zeilen\nmit\nStatusmeldungen'
BoxLayout:
size_hint_x: 0.5
padding: 5
ToggleButton:
text: "Automatik-\nBetrieb"
on_press: app.testfunktion()
In the same way, as you extended Popup you can also extend MyPopup you created. I implemented it for the first two Popups. It is straightforward to extend it. If you still have a question ask in the comments.
All the features MyPopup has are also in MyPopup1 because it extends MyPopup. The title should be different and the previous and next are different for each Popup. Therefore you need to specify them.
<MyPopup1#MyPopup>:
title: "Popup Window No. 1"
call_previous:
call_next: "Factory.MyPopup2().open()"
I am using eval in the MyPopup to "evaluate" these statements which are part of the root. See this extract from MyPopup:
on_release: eval(root.call_next)
Alternatively you could also give them just numbers and use maybe sth similar, but I'll leave that up to you.
#:import Factory kivy.factory.Factory
<MyPopup1#MyPopup>:
title: "Popup Window No. 1"
call_previous:
call_next: "Factory.MyPopup2().open()"
<MyPopup2#MyPopup>:
title: "Popup Window No. 2"
call_previous: "Factory.MyPopup1().open()"
call_next: "Factory.MyPopup2().open()"
<MyPopup#Popup>:
auto_dismiss: False
size_hint: None,None
size: 400,300
BoxLayout:
orientation: "vertical"
BoxLayout:
orientation: "vertical"
BoxLayout:
Label:
text: 'Circuit Active:'
Switch:
id: "switch1"
BoxLayout:
Label:
text: 'Default Watering Time: [min]'
TextInput:
text: '30'
BoxLayout:
Label:
text: 'Watering Group'
TextInput:
text: '3'
BoxLayout:
Button:
text: 'Previous'
on_release: root.dismiss()
on_release: eval(root.call_previous)
Button:
text: 'Cancel'
on_release: root.dismiss()
Button:
text: 'Save + Exit'
Button:
text: 'Next'
on_release: root.dismiss()
on_release: eval(root.call_next)
BoxLayout:
orientation: "vertical"
padding: 5
BoxLayout:
BoxLayout:
padding: 5
ToggleButton:
text: "Wasserkreis 1"
# disabled: True
on_release: Factory.MyPopup1().open()
BoxLayout:
padding: 5
ToggleButton:
text: "Wasserkreis 2"
BoxLayout:
padding: 5
ToggleButton:
text: "Wasserkreis 3"
BoxLayout:
BoxLayout:
padding: 5
ToggleButton:
text: "Wasserkreis 4"
BoxLayout:
padding: 5
ToggleButton:
text: "Wasserkreis 5"
BoxLayout:
padding: 5
ToggleButton:
text: "Wasserkreis 6"
BoxLayout:
BoxLayout:
padding: 5
Label:
text: 'Drei Zeilen\nmit\nStatusmeldungen'
BoxLayout:
size_hint_x: 0.5
padding: 5
ToggleButton:
text: "Automatik-\nBetrieb"
on_press: app.testfunktion()

ScrollView in a anchorlayout. python. kivy

practice screen
This is from the .py file
The screens are controlled by screen manager as you can see
class Practice_Page(Screen):
pass
class PracticeList(BoxLayout):
def practicelist(ScrollView):
practicelist.bind(minimum_height=layout.setter('height'))
.KV file:
<Practice_page>:
canvas.before:
Rectangle:
pos: self.pos
size: self.size
source: 'background1.png'
AnchorLayout:
anchor_x: 'center'
anchor_y: 'center'
PracticeList:
size: 900,30
size_hint: None,None
do_scroll_x: False
BoxLayout:
orientation: 'vertical'
padding: 10
cols: 1
Button:
text: 'The Real Number System'
on_press: root.manager.current = 'open_topics'
Button:
text: 'Absolute Value'
on_press: root.manager.current = 'open_practice'
Button:
text: 'Operations W/ Integers & Fractions'
on_press: root.manager.current = 'open_topics'
Button:
text: 'Operations W/ Zero'
on_press: root.manager.current = 'open_formulas'
I have about 30 more buttons. I have no idea what I'm doing wrong, any help or suggestions will be very helpful.
AnchorLayout:
anchor_x: 'center'
anchor_y: 'center'
ScrollView:
#size: 900,30
size: self.size
#do_scroll_x: False
GridLayout:
# orientation: 'vertical'
#padding: 10
size_hint_y: None
height: self.minimum_height
cols: 1
Button:
size_hint_y: None
text: 'The Real Number System'
on_press: root.manager.current = 'open_topics'
Button:
size_hint_y: None
text: 'Absolute Value'
on_press: root.manager.current = 'open_practice'
Button:
size_hint_y: None
text: 'Operations W/ Integers & Fractions'
on_press: root.manager.current = 'open_topics'
Button:
size_hint_y: None
text: 'Operations W/ Zero'
on_press: root.manager.current = 'open_formulas'
##MORE BTNS
For anyone who needs it.

How to bind using kivy only?

I want to create a Widget changing only the text of a label inside it, but all the ways I find how to change this are by changing it in the python code instead of reusing only Kivy objects.
So I have a widget like the following:
<AmiLabel#Label>
color: .1, .5, .8, 1
font_size: 16
<AmiTextInput#TextInput>
font_size: 16
<PropertyInputForm>:
BoxLayout:
size: root.size
pos: root.pos
orientation: 'horizontal'
AmiLabel:
text: 'Folder Location'
size_hint_x: .5
AmiTextInput:
text: 'None'
size_hint_x: .5
<MainFormWidget>:
BoxLayout:
size: root.size
pos: root.pos
id: foo_bar
padding: 5
spacing: 5
canvas:
Color:
rgb: (1, 1, 1)
Rectangle:
pos: self.pos
size: self.size
orientation: 'vertical'
AmiLabel:
height: 36
size_hint_x: 1
size_hint_y: None
text: 'Project Name'
PropertyInputForm:
height: 36
size_hint_x: 1
size_hint_y: None
# I WANT TO CHANGE THE TEXT OF THE LABEL IN HERE
PropertyInputForm:
height: 36
size_hint_x: 1
size_hint_y: None
# I WANT TO CHANGE THE TEXT OF THE LABEL IN HERE
All I want to is change the text of the label from another widget in another level without touching the python code.
¿Is that possible?
One simple way would be to add a new property to your PropertyInputForm and reference or set that.
<PropertyInputForm>:
new_text_property: ''
BoxLayout:
size: root.size
pos: root.pos
orientation: 'horizontal'
AmiLabel:
text: root.new_text_property
size_hint_x: .5
AmiTextInput:
text: 'None'
size_hint_x: .5
and later
PropertyInputForm:
height: 36
size_hint_x: 1
size_hint_y: None
new_text_property: 'whatever'
You may also need to declare new_text_property in the python class to have it be a StringProperty rather than an ObjectProperty, though even that is I think not necessary in kivy 1.8.

Categories