how to bind a custom widget defined in .kv from python

1,244 views
Skip to first unread message

emsoss

unread,
Nov 19, 2016, 10:54:49 PM11/19/16
to Kivy users support
i need help binding a button widget that was created in .kv. my program worked before but because i was unable to create the lay iout i wanted in python, i had to do it in my .kv file. now i am have a problem binding to it in python. 


here is the .kv file

<widgets>: 
    Button:
        #on_release:print self.ids.name.text
        pos: self.parent.pos
        size: self.parent.size
        StackLayout:
        
            pos: self.parent.pos
            size: self.parent.size
            orientation: 'lr-tb'
            Label:
                id:location
                size_hint: .3,.5
                text: 'self.location'
                text_size:self.size
                halign:'left'
                valign:'middle'

            Label:
                id:name
                size_hint: .5,.5
                text_size:self.size
                text: 'self.text'
                halign:'left'
                valign:'middle'

            Label:
                id:time
                size_hint: .2,.5
                text: 'self.time'
                text_size:self.size

                halign:'left'
                valign:'middle'

            Label:
                id:message
                size_hint:1,.5
                text_size:self.size
                text:'self.message'
                halign:'left'
                valign:'middle'


.py file 

class widgets(Widget):
    pass


class ScreenManagement(ScreenManager,):

      def display(self):

                self.btn=widgets(id=btn_id,background_color=coleur,background_normal='')
                self.btn.ids.time.text=str(self.tim)
                self.btn.ids.name.text=name
                #self.btn.ids.
                self.btn.ids.location.text=room
                self.btn.ids.message.text=own_message
              
                self.btn.bind(on_release=partial(self.btn_pressed,self.btn.id)) # when a user button is pressed call the btn_pressed function
                self.btn.bind(on_release=self.change_screen)
                self.ids.grid.add_widget(self.btn)
                print 'here'



in the above code, replacing     self.btn=widgets(id=btn_id,background_color=coleur,background_normal='')  by self.btn=Button()  makes the binding work.
what i'm missing


ZenCODE

unread,
Nov 20, 2016, 1:15:57 AM11/20/16
to Kivy users support
Okay, these is too much missing here to try and run it. One thing. Your widget classname should be capitalized. i.e.

    class Widgets(Widget):

Then try making the code runnable and explain exactly what you want to happen.

emsoss

unread,
Nov 20, 2016, 10:49:21 AM11/20/16
to Kivy users support
here is a runnable code. when the button is pressed, i would like to call a function which changes the screen. now it seem like the binding is not working.

.py file

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.stacklayout import StackLayout
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.properties import ObjectProperty
from kivy.factory import Factory
from kivy.app import App
from kivy.uix.scrollview import ScrollView
from kivy.uix.gridlayout import GridLayout
from kivy.uix.button import Button
from kivy.uix.screenmanager import ScreenManager
from kivy.uix.boxlayout import BoxLayout
import redis
from kivy.graphics import Color
from kivy.uix.widget import Widget

class widgets(Widget):
    pass

class ScreenManagement(ScreenManager):
    def change_screen(self,*args):                                    #need to understand this
        App.get_running_app().root.current = 'choice'
    
    def add_btn(self):
        for i in range(10):
            self.btn=widgets(id=str(i))
            self.btn.ids.time.text=str(i)
            self.btn.ids.name.text=str(i)
            self.btn.ids.location.text=str(i)
            self.btn.ids.message.text=str(i)
            #.btn.bind(on_release=partial(self.btn_pressed,self.btn.id)) # when a user button is pressed call the btn_pressed function
            self.btn.bind(on_release=self.change_screen)
            self.ids.grid.add_widget(self.btn)
                
class yourApp(App):
    pass

if __name__ == '__main__':
    yourApp().run()
         


.kv file

<Widgets>: 
    Button:
        pos: self.parent.pos
        size: self.parent.size
        StackLayout:
            padding:(5,5,5,5)
ScreenManagement:   
    Screen:
        BoxLayout:
            orientation:'vertical'
            ScrollView:
                GridLayout:
                    size_hint_y:None
                    row_default_height:100
                    id:grid
                    cols:1
                    Button:
                        on_press:root.add_btn()
        
    Screen:
        name: 'choice'
        canvas:
            Color:
                rgb:0.5,.8,1
            Rectangle:
                pos: self.pos
                size: self.size
        BoxLayout:
        
















emsoss

unread,
Nov 20, 2016, 5:46:03 PM11/20/16
to Kivy users support
i found a way around by doing this in .kv file:   on_press: root.call_back() wherre call_back() is a fx defined in python. i'm still interested in how i could have done the binding in python. 

ZenCODE

unread,
Nov 21, 2016, 2:43:09 PM11/21/16
to Kivy users support
I get a blank screen when I run your code. Probably because you app does not have a build method?

Anyway, everything you can do it kv you can do in Python. Your python probably did not work because a Widget does not define an 'on_release' event: only a button does. SO inheriting from Widget will not give you an 'on_release' event. You could test that by making your (capitalized) Widgets class inherit from Button, not Widget? But in your code, the Widgets contains a bunch of other widgets, so should rather be layout.

But anyway, you got it working. Play on :-)
Reply all
Reply to author
Forward
0 new messages