Kivy class in .py and .kv interaction 2

2019-09-04 01:29发布

问题:

Follow up from Kivy class in .py and .kv interaction , but more complex.

Here is the full code of what I'm writing:

The data/screens/learnkanji_want.kv has how I want the code to be, but I don't fully understand how the class KanjiOriginScreen() plays it's role in screen management.

data/screens/learnkanji.kv works how I want it, but for this to work I have to put keyb_height in class KanjiOriginScreen() (main.py). However I want that code to be in the class LayoutFunction() (learnkanji.py).

Question

How can I put keyb_height in the function LayoutFunction() and access this in the .kv file in <LayoutFunction>?

Could you also explain why KanjiOriginScreen: can be put in learnkanji.kv without < > and the program still recognizes it should use this?

If anything is unclear, please ask :)

Edit

I found out that I didn't import the learnkanji.py in the learnkanji.kv file and that caused that it couldn't find the class 'LayoutFunction'.

#:import learnkanji data.screens.learnkanji

回答1:

To answer your questions:

  1. The way you are doing it should work. You should be able to access object attributes from kv. If your attribute is going to change, however, and you want the UI to update when it does, you should use Kivy Properties. If it is constant, a normal attribute works fine.

  2. From the Kivy Docs, <Widget>: is a class rule that will be applied to every instance of that class. Widget: will create an actual instance of that class (in this case it is your root widget).

As for ScreenManager and Screens, you can think of them this way. Each Screen is it's own individual UI (it's own root widget). The screen manager is a container that holds your Screen and can swap between different Screens. This lets you create separate UIs that you can toggle between. Each UI is a separate widget tree with a Screen at its root. The docs are actually pretty good at describing ScreenManager.



回答2:

How can I put keyb_height in the function LayoutFunction() and access this in the .kv file in ?

You can't do this with a function. You need to make LayoutFunction into a class to do this. Like so:

main.py

class LayoutClass(BoxLayout): # I made it a boxlayout, you could make it anything you want

    keyb_height = NumericProperty(260) # from kivy.properties import NumericProperty

kv file:

<LayoutClass>: # can only access it this way if it's a class in main.py

    something: root.keyb_height

Could you also explain why KanjiOriginScreen: can be put in learnkanji.kv without < > and the program still recognizes it should use this?

It sounds like you're asking how you can achieve this.. but I can't think why? Unless you want it managed by a ScreenManager perhaps? However, the only way you can have KanjiOriginScreen within the kv file without the <> is if it is inside another root widget. For instance, see Testy and ScreenTwo as they are in the kv file under <Manager> in my answer to your other question(here). They are without <> because they are class instances, WITHIN another class(the Manager class). Only root widgets have the <> around them in the kv file. If none of this makes sense to you, you need to do a tutorial on kivy.

Check out this tutorial I made a while back, it explains a little about root widgets in kv(at around 4.30).



回答3:

Sorry I was not clear with my question, but with the help on IRC on #Kivy I ended up with the following:

learnkanji.py

class LayoutFunctioning(BoxLayout):
    keyb_height = NumericProperty(260)

learnkanji.kv

KanjiOriginScreen:
    name: 'LearnKanji'
    fullscreen: True

    LayoutFunction:
        id: lfunc
        #...code...
        height: lfunc.keyb_height #Instead of root.keyb_height

Now I understand how to use the id, I can use lfunc to call my code in LayoutFunction() :)