简体   繁体   English

Python Kivy如何将使用Python制作的小部件注入以在kv文件中进行布局

[英]Python Kivy How to inject widgets made with Python to layout in kv file

I have written a python kivy application for displaying measurements. 我已经编写了一个python kivy应用程序来显示测量值。 While searching stuff on kivy I stumbled on the the kivy-md (Material Design for kivy) project. 在搜索kivy上的东西时,我偶然发现了kivy-md(用于kivy的材料设计)项目。 I find the UI very good looking. 我发现用户界面很好看。 That is why I want to inject my app into a screen of the kivy-md project. 这就是为什么我要将我的应用程序注入kivy-md项目的屏幕。

My project is inside a folder kivy-playground which contains the kivymd files in a folder kivymd , the main.py (for starting the kivy md application), the main.kv file (for the layout of the kivy md application) and a playground.py which contains the kivy application for displaying measurements. 我的项目是一个文件夹内kivy-playground其中包含kivymd在一个文件夹中的文件kivymd ,在main.py (用于启动kivy MD应用程序),将main.kv文件(用于kivy MD应用程序的布局)和playground.py包含用于显示测量值的kivy应用程序。 I am using Python 3.7 with the latest version of kivy. 我将Python 3.7与最新版本的kivy一起使用。

Goal : I want to inject the Application view from playground.py into the main application which is started by the main.py such that the view of the playground.py is displayed on the screen page2 (see main.kv ) of the main application. 目标 :我想从应用程序视图注入playground.py成由开始的主要应用main.py使得观playground.py显示在屏幕page2 (见main.kv )主要应用。 I am totally lost how this can be achieved and I would be happy if someone could show me on this toy example how this can be achieved. 我完全迷失了如何实现这一目标,如果有人可以在这个玩具示例中向我展示如何实现这一目标,我将非常高兴。 It is not necessarily important that the playground.py stays as it is. 它不一定是重要的playground.py保持原样。 If the problem can be solved by small changes in the playground.py file then this would be also a valid solution. 如果可以通过在playground.py文件中进行较小的更改来解决问题,那么这也是一种有效的解决方案。

I tried to cook up a minimal working example. 我试图做一个最小的工作示例。 Here are the files 这是文件

# main.py
# -*- coding: utf-8 -*-

import os

from kivy.app import App
from kivy.core.window import Window
from kivy.lang import Builder
from kivymd.theming import ThemeManager


class MainApp(App):

    theme_cls = ThemeManager()

    def __init__(self, **kwargs):
        super(MainApp, self).__init__(**kwargs)
        Window.bind(on_close=self.on_stop)

    def build(self):
        main_widget = Builder.load_file(
            os.path.join(os.path.dirname(__file__), "./main.kv")
        )
        self.theme_cls.theme_style = 'Dark'
        return main_widget

    def close_app(self, *largs):
        super(MainApp, self).stop(*largs)

    def on_pause(self):
        return True


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

here is the main.kv 这是main.kv

# main.kv
#:kivy 1.10.1
#:import Toolbar kivymd.toolbar.Toolbar
#:import MDNavigationDrawer kivymd.navigationdrawer.MDNavigationDrawer
#:import NavigationLayout kivymd.navigationdrawer.NavigationLayout
#:import NavigationDrawerToolbar kivymd.navigationdrawer.NavigationDrawerToolbar

NavigationLayout:
    id: nav_layout
    MDNavigationDrawer:
        id: nav_drawer
        NavigationDrawerToolbar:
        NavigationDrawerIconButton:
            icon: 'checkbox-blank-circle'
            text: "Page1"
            on_release: app.root.ids.scr_mngr.current = 'page1'
        NavigationDrawerIconButton:
            icon: 'checkbox-blank-circle'
            text: "Page2"
            on_release: app.root.ids.scr_mngr.current = 'page2'
    BoxLayout:
        orientation: 'vertical'
        halign: "center"
        Toolbar:
            id: toolbar
            md_bg_color: app.theme_cls.primary_color
            background_palette: 'Primary'
            background_hue: '500'
            right_action_items: [['dots-vertical', lambda x: app.root.toggle_nav_drawer()]]
        ScreenManager:
            id: scr_mngr
            Screen:
                name: 'page1'
                Label:
                    text: "page1"
            Screen:
                name: 'page2'
                Label:
                    text: "Page 2"

and here is the playground.py which I want to inject into the screen page2 of the main application. 这里是playground.py我要注入到屏幕page2的主要应用。

from kivy.app import App
from kivy.uix.label import Label


class Playground(App):

    def build(self):
        hello_world_label = Label(text="Hello World!")
        return hello_world_label


if __name__ == "__main__":
    Playground().run()

If you can change Playground.py to something like this: 如果可以将Playground.py更改为以下内容:

from kivy.app import App
from kivy.uix.label import Label

def getPlaygroundRoot():
    hello_world_label = Label(text="Hello World!")
    return hello_world_label


class PlayGround(FloatLayout):
    def __init__(self, **kwargs):
        super(PlayGround, self).__init__(**kwargs)
        self.add_widget(getPlaygroundRoot())

class Playground(App):

    def build(self):
        return getPlaygroundRoot()


if __name__ == "__main__":
    Playground().run()

Then, in your main.py , you can add: 然后,在main.py ,可以添加:

from playGround import getPlaygroundRoot

And then use add_widget(getPlaygroundRoot()) to add the Playground root to some container in the MainApp . 然后使用add_widget(getPlaygroundRoot())Playground根目录添加到MainApp某个容器中。

Or, if you want to use Playground in your .kv file, you can add #:import playground playGround to your .kv file, and then add: 或者,如果您想在.kv文件中使用Playground ,则可以将#:import playground playGround添加到.kv文件中,然后添加:

        Screen:
            name: 'page2'
            Label:
                text: "Page 2"
                pos_hint: {'center_x': 0.5, 'y': 0.8}
                size_hint: (1.0, 0.2)
            PlayGround:
                pos_hint: {'center_x': 0.5, 'y': 0.1}
                size_hint: (1.0, 0.2)

to add it to your page2 . 将其添加到您的page2

  • If there is a kv file, playground.kv for playground.py then use include <file> in main.kv 如果有一个文件KV,playground.kvplayground.py然后使用include <file>main.kv
  • Add import statement, from playground import PlayGround in main.py from playground import PlayGround main.py中的 from playground import PlayGround添加导入语句

Kivy Lang Directives » include <file> Kivy Lang指令»include <文件>

 include <file> 

Syntax: 句法:

 #:include [force] <file> 

Includes an external kivy file. 包括一个外部的kivy文件。 This allows you to split complex widgets into their own files. 这使您可以将复杂的窗口小部件拆分为它们自己的文件。 If the include is forced, the file will first be unloaded and then reloaded again. 如果强制包含,则将首先卸载文件,然后再次重新加载。

Snippets 片段

playground.py 游乐场

from kivy.app import App
from kivy.uix.label import Label


class PlayGround(Label):
    pass


class Playground(App):

    def build(self):
        return PlayGround()


if __name__ == "__main__":
    Playground().run()

playground.kv 操场

#:kivy 1.11.0

<PlayGround>:
    text: "Hello World!"

min.py 最低

# main.py
# -*- coding: utf-8 -*-

import os

from kivy.app import App
from kivy.core.window import Window
from kivy.lang import Builder
from kivymd.theming import ThemeManager
from playground import PlayGround


class MainApp(App):

main.kv 主.kv

# main.kv
#:kivy 1.10.1
#:import Toolbar kivymd.toolbar.Toolbar
#:import MDNavigationDrawer kivymd.navigationdrawer.MDNavigationDrawer
#:import NavigationLayout kivymd.navigationdrawer.NavigationLayout
#:import NavigationDrawerToolbar kivymd.navigationdrawer.NavigationDrawerToolbar

#:include playground.kv

NavigationLayout:
    ...
        ScreenManager:
            id: scr_mngr
            Screen:
                name: 'page1'
                Label:
                    text: "page1"
            Screen:
                name: 'page2'
                Label:
                    text: "Page 2"
                PlayGround:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM