Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
424 views
in Technique[技术] by (71.8m points)

python - Use custom widgets kivy

I'm trying to build a kivy app using some custom widgets. However whenever I try to use them they never work with my layout. Using a normal button:

import kivy
kivy.require('1.8.0')

from kivy.app import App
from kivy.uix.widget import Widget
from kivy.properties import ListProperty

class RootWidget(Widget):pass

class myApp(App):

    def build(self):
        global rw
        rw  = RootWidget()
        return rw

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

#:kivy 1.8.0

<RootWidget>:

    BoxLayout:
        size: root.size
        orientation: 'horizontal'
        spacing: 10
        padding: 10

        Button:
            id: abut
            text: "Custom Button"

This works as expected, my Button basically takes up the entire window. However when I try replacing the Button with my custom button

import kivy
kivy.require('1.8.0')

from kivy.app import App
from kivy.uix.widget import Widget
from kivy.properties import ListProperty

class MyWidget(Widget):

     pressed = ListProperty([0, 0])

     def on_touch_down(self, touch):
         if self.collide_point(*touch.pos):
             self.pressed = touch.pos
             return True
         return super(MyWidget, self).on_touch_down(touch)

     def on_pressed(self, instance, pos):
         print ('pressed at {pos}'.format(pos=pos))

class RootWidget(Widget):pass

class someApp(App):

    def build(self):
        global rw
        rw  = RootWidget()
        return rw

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

#:kivy 1.8.0

<MyWidget>:
    BoxLayout:
        orientation: 'horizontal'
        spacing: 10

        Button:
            id: abut
            text: "Custom Button"        

<RootWidget>:

    BoxLayout:
        size: root.size
        orientation: 'horizontal'
        spacing: 10
        padding: 10

        MyWidget:

it only appears in the bottom left-hand corner of the window and doesn't behave like a button. What am I missing?

Furthermore, is it even necessary to create a custom button this way? The kivy tutorials used this sort of method to make their custom button but can't I just do something like this

Button:
    on_press: root.do_action()

to make each button behave differently?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Your actual problem is that although your MyWidget is placed in a BoxLayout in the kv file, its child BoxLayout does not have its size set to the MyWidget size, and therefore just maintains the default size and position of (100, 100) in the bottom left of the screen.

You can fix this by giving it the extra size: root.size rule as you did within the <RootWidget> rule, or actually normally it's easier to just use a BoxLayout (i.e. subclass BoxLayout instead of Widget) which of course gives you the automatic resizing/positioning for free.

Also, as Joran said, if you just want to do something when the button is pressed you can use the second method...that's what you're intended to do! I don't know what example you are looking at, but you wouldn't normally need a complex arrangement like yours.

You might also be interested to know that in the most recent release (1.8) the button behavior has been abstracted to a ButtonBehavior class that handles detecting touches and dispatching on_press etc. appropriately. The Behavior isn't a widget, so you can subclass it with any other widget to make anything into a button!


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...