【问题标题】:Using ScreenManager in Kivy (Python) with several .py screens在具有多个 .py 屏幕的 Kivy (Python) 中使用 ScreenManager
【发布时间】:2023-01-24 04:41:55
【问题描述】:

我最近开始使用 Kivy 框架来创建一个我想合并的具有多个屏幕的应用程序,例如,在登录屏幕上按一个按钮会打开另一个页面。几天来我一直在尝试使用 ScreenManager 库,但我无法让它工作,互联网上有几个教程,但每个人都使用不同的变体。下面我附上登录页面的代码,按下“登录”按钮,第二个屏幕应该打开。

登录.py:

from kivy.core.text import LabelBase
from kivy.lang import Builder
from kivy.core.window import Window
from kivymd.app import MDApp

Window.size = (350, 580)

kv = """
MDFloatLayout:
    md_bg_color: 0, 0, 0, 1
    Image:
        source: "img\\logo5.png"
        pos_hint: {"center_x": .5, "center_y": .85}
        size_hint: .18, .18
    MDFloatLayout:
        size_hint: .9, .07
        pos_hint: {"center_x": .5, "center_y": .68}
        canvas:
            Color:
                rgb: 250/255, 250/255, 250/255, 1
            RoundedRectangle:
                size: self.size
                pos:self.pos
                radius: [4]
        canvas.before:
            Color:
                rgb: 217/255, 217/255, 217/255, 1
            Line:
                width: 1.1
                rounded_rectangle: self.x, self.y, self.width, self.height, 4, 4, 4, 4, 100
        TextInput:
            hint_text: "Phone number, username or e-mail"
            size_hint: 1, None
            pos_hint: {"center_x": .5, "center_y": .5}
            height: self.minimum_height
            background_color: 1, 1, 1, 0
            font_size: "14sp"
            font_name: "MRoboto"
            hint_text_color: 170/255, 170/255, 170/255, 1
            padding: 13
            cursor_color: 0, 0, 0, 1
    MDFloatLayout:
        size_hint: .9, .07
        pos_hint: {"center_x": .5, "center_y": .59}
        canvas:
            Color:
                rgb: 250/255, 250/255, 250/255, 1
            RoundedRectangle:
                size: self.size
                pos:self.pos
                radius: [4]
        canvas.before:
            Color:
                rgb: 217/255, 217/255, 217/255, 1
            Line:
                width: 1.1
                rounded_rectangle: self.x, self.y, self.width, self.height, 4, 4, 4, 4, 100
        TextInput:
            hint_text: "Password"
            size_hint: 1, None
            pos_hint: {"center_x": .5, "center_y": .5}
            height: self.minimum_height
            background_color: 1, 1, 1, 0
            font_size: "14sp"
            font_name: "MRoboto"
            password: "true"
            hint_text_color: 170/255, 170/255, 170/255, 1
            padding: 13
            cursor_color: 0, 0, 0, 1
    Button:
        text: "Log in"
        color: 1, 1, 1, 1
        size_hint: .9, .07
        pos_hint: {"center_x": .5, "center_y": .43}
        background_color: 1, 1, 1, 0
        font_size: "13sp"
        font_name: "BRoboto"
        canvas.before:
            Color:
                rgb: 98/255, 170/255, 243/255, 1
            RoundedRectangle:
                size: self.size
                pos: self.pos
                radius: [4]
    MDLabel:
        text: "Don't have an account?"
        color: 172/255, 172/255, 172/255, 1
        pos_hint: {"center_x": .74, "center_y": .095}
        font_size: "13sp"
        font_name: "MRoboto"
    MDTextButton:
        text: "Sign up"
        color: 98/255, 170/255, 243/255, 1
        pos_hint: {"center_x": .685, "center_y": .095}
        font_size: "13sp"
        font_name: "MRoboto"
    MDCheckbox:
        size_hint: None, None
        size: "48dp", "48dp"
        pos_hint: {"center_x": .1, "center_x": .1}
        on_active: app.show_password(*args)
    MDLabel:
        id: password_text
        text: "Show Password"
        pos_hint: {"center_x": .7, "center_x": .43}
"""
class Login(MDApp):

    def build(self):
        return Builder.load_string(kv)

    def show_password(self, checkbox, value):
        if value:
            self.root.ids.password.password = False
            self.root.ids.password_text.text = "Hide Password"
        else:
            self.root.ids.password.password = True
            self.root.ids.password_text.text = "Show Password"

if __name__ == "__main__":
    LabelBase.register(name="BRoboto", fn_regular="font\\Roboto-Bold.ttf")
    LabelBase.register(name="MRoboto", fn_regular="font\\Roboto-Medium.ttf")
    Login().run()

列表.py:

from kivy.core.window import Window
from kivy.lang import Builder
from kivy.factory import Factory
from kivy.uix.image import Image
from kivymd.app import MDApp
from kivymd.uix.list import IRightBodyTouch, ILeftBody
from kivymd.uix.selectioncontrol import MDCheckbox

Window.size = (350, 580)

kv = """
<ListItemWithCheckbox@OneLineAvatarIconListItem>:
    MyAvatar:
        source: "data/logo/kivy-icon-128.png"
    MyCheckbox:

<Lists@BoxLayout>
    name: "lists"
    orientation: "vertical"

    MDTopAppBar:
        title:"Hide the story to:"
        md_bg_color: app.theme_cls.primary_color
        elevation: 3

    ScrollView:

        MDList:
            id: scroll
"""

Builder.load_string(kv)

class MyCheckbox(IRightBodyTouch, MDCheckbox):
    pass

class MyAvatar(ILeftBody, Image):
    pass

class Users(MDApp):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)

    def build(self):
        self.title = "Liste"
        self.theme_cls.primary_palette = "Teal"
        self.theme_cls.theme_style = "Dark"
        list = Factory.Lists()
        for i in range(30):
            list.ids.scroll.add_widget(Factory.ListItemWithCheckbox(text="Item %d" % i))
        self.root = list

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

在我的测试中,我尝试在 login.py 代码和从头创建的第三个新文件中实例化 ScreenManager。提前致谢。

【问题讨论】:

  • 首先,此代码需要在单个应用程序中。没有理由创建两个单独的主要功能。
  • 嗨马克,首先感谢您的回复。由于我还在积累经验,创建这两个屏幕我主要依靠两个在线教程,然后我根据需要修改代码。事实证明,我创建了两个文件,它们实际上代表了两个不同的应用程序。我应该如何着手制作“一体机”?

标签: python kivy kivy-language kivymd


【解决方案1】:

我更新了你的代码,所以一切都在 login.py 中。它使用屏幕管理器在屏幕之间切换。 您还可以将列表类放在 list.py 文件中,并将它使用的导入移动到该文件。

from kivy.lang import Builder
from kivy.core.window import Window
from kivymd.app import MDApp
from kivymd.uix.screen import MDScreen
from kivymd.uix.screenmanager import MDScreenManager
from kivy.factory import Factory
from kivy.uix.image import Image
from kivymd import app
from kivymd.uix.list import IRightBodyTouch, ILeftBody
from kivymd.uix.selectioncontrol import MDCheckbox

Window.size = (350, 580)

kv = """
WindowManager:
    id: manager
    LoginScreen:
        id: login_screen
    ListScreen:
        id: list_screen

<LoginScreen>:
    name: 'login_screen'
    MDFloatLayout:
        md_bg_color: 0, 0, 0, 1
        Image:
            source: "img_logo5.png"
            pos_hint: {"center_x": .5, "center_y": .85}
            size_hint: .18, .18
        MDFloatLayout:
            size_hint: .9, .07
            pos_hint: {"center_x": .5, "center_y": .68}
            canvas:
                Color:
                    rgb: 250/255, 250/255, 250/255, 1
                RoundedRectangle:
                    size: self.size
                    pos:self.pos
                    radius: [4]
            canvas.before:
                Color:
                    rgb: 217/255, 217/255, 217/255, 1
                Line:
                    width: 1.1
                    rounded_rectangle: self.x, self.y, self.width, self.height, 4, 4, 4, 4, 100
            TextInput:
                hint_text: "Phone number, username or e-mail"
                size_hint: 1, None
                pos_hint: {"center_x": .5, "center_y": .5}
                height: self.minimum_height
                background_color: 1, 1, 1, 0
                font_size: "14sp"
                # font_name: "MRoboto"
                hint_text_color: 170/255, 170/255, 170/255, 1
                padding: 13
                cursor_color: 0, 0, 0, 1
        MDFloatLayout:
            size_hint: .9, .07
            pos_hint: {"center_x": .5, "center_y": .59}
            canvas:
                Color:
                    rgb: 250/255, 250/255, 250/255, 1
                RoundedRectangle:
                    size: self.size
                    pos:self.pos
                    radius: [4]
            canvas.before:
                Color:
                    rgb: 217/255, 217/255, 217/255, 1
                Line:
                    width: 1.1
                    rounded_rectangle: self.x, self.y, self.width, self.height, 4, 4, 4, 4, 100
            TextInput:
                hint_text: "Password"
                size_hint: 1, None
                pos_hint: {"center_x": .5, "center_y": .5}
                height: self.minimum_height
                background_color: 1, 1, 1, 0
                font_size: "14sp"
                # font_name: "MRoboto"
                password: "true"
                hint_text_color: 170/255, 170/255, 170/255, 1
                padding: 13
                cursor_color: 0, 0, 0, 1
        Button:
            text: "Log in"
            color: 1, 1, 1, 1
            size_hint: .9, .07
            pos_hint: {"center_x": .5, "center_y": .43}
            background_color: 1, 1, 1, 0
            font_size: "13sp"
            # font_name: "BRoboto"
            canvas.before:
                Color:
                    rgb: 98/255, 170/255, 243/255, 1
                RoundedRectangle:
                    size: self.size
                    pos: self.pos
                    radius: [4]
            on_release: root.manager.current = 'list_screen'
        MDLabel:
            text: "Don't have an account?"
            color: 172/255, 172/255, 172/255, 1
            pos_hint: {"center_x": .74, "center_y": .095}
            font_size: "13sp"
            # font_name: "MRoboto"
        MDTextButton:
            text: "Sign up"
            color: 98/255, 170/255, 243/255, 1
            pos_hint: {"center_x": .685, "center_y": .095}
            font_size: "13sp"
            # font_name: "MRoboto"
        MDCheckbox:
            size_hint: None, None
            size: "48dp", "48dp"
            pos_hint: {"center_x": .1, "center_x": .1}
            on_active: app.show_password(*args)
        MDLabel:
            id: password_text
            text: "Show Password"
            pos_hint: {"center_x": .7, "center_x": .43}
            
<ListItemWithCheckbox@OneLineAvatarIconListItem>:
    MyAvatar:
        source: "data/logo/kivy-icon-128.png"
    MyCheckbox:
    
<ListScreen>
    name: 'list_screen'
    BoxLayout
        name: "lists"
        orientation: "vertical"
    
        MDTopAppBar:
            title:"Hide the story to:"
            md_bg_color: app.theme_cls.primary_color
            elevation: 3
    
        ScrollView:
    
            MDList:
                id: scroll
"""


class WindowManager(MDScreenManager):
    """ Window Manager """
    pass


class ListItemWithCheckbox:
    pass


class LoginScreen(MDScreen):
    pass


class Login(MDApp):

    def build(self):
        return Builder.load_string(kv)

    def show_password(self, checkbox, value):
        if value:
            self.root.ids.password.password = False
            self.root.ids.password_text.text = "Hide Password"
        else:
            self.root.ids.password.password = True
            self.root.ids.password_text.text = "Show Password"


class MyCheckbox(IRightBodyTouch, MDCheckbox):
    pass


class MyAvatar(ILeftBody, Image):
    pass


class ListItemWithCheckbox:
    pass


class ListScreen(MDScreen):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)

    def on_enter(self):
        app.title = "Liste"
        # my_list = Factory.Lists()
        for i in range(30):
            self.ids.scroll.add_widget(Factory.ListItemWithCheckbox(text="Item %d" % i))
        # self.root = list


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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-25
    • 1970-01-01
    • 1970-01-01
    • 2019-04-22
    • 1970-01-01
    相关资源
    最近更新 更多