无法从Kivy对象获取ID

时间:2019-11-24 17:23:35

标签: python kivy kivy-language

我正在尝试将ObjectProperty()与id一起使用,但无法正常工作。我了解ObjectProperty的方式是variablename = ObjectProperty()作为对.kv文件中名为variablename的类的引用,但由于我收到以下错误,所以我误解了某些内容:swiper_manager = MySwiperManager.ids.swiper_manager AttributeError: 'kivy.properties.ObjectProperty' object has no attribute 'ids'

.py文件

from kivy.uix.boxlayout import BoxLayout
from kivy.uix.screenmanager import Screen
from kivy.properties import ObjectProperty
from kivy.lang import Builder

from kivymd.uix.managerswiper import MDSwiperPagination
from kivymd.theming import ThemeManager

Builder.load_file("Prelogin/prescreenmanger.kv")

class MySwiperManager(BoxLayout):
    pass

class PreScreenManager(Screen):
    theme_cls = ThemeManager()
    theme_cls.primary_palette = 'Indigo'
    MySwiperManager = ObjectProperty()
    swiper_manager = MySwiperManager.ids.swiper_manager
    paginator = MDSwiperPagination()
    paginator.screens = swiper_manager.screen_names
    paginator.manager = swiper_manager
    swiper_manager.paginator = paginator
    MySwiperManager.add_widget(paginator)

.kv文件

<ScreenOne@Screen>:
    name: 'screen one'
    Label: 
        text: 'Hello World'

<ScreenTwo@Screen>:
    name: 'screen two'


<ScreenThree@Screen>:
    name: 'screen three'


<ScreenFour@Screen>:
    name: 'screen four'



<ScreenFive@Screen>:
    name: 'screen five'


<PreScreenManager>:
    MySwiperManager:
        orientation: 'vertical'
        id: MySwiperManager

        MDSwiperManager:
            id: swiper_manager

            ScreenOne: 

            ScreenTwo:

            ScreenThree:

            ScreenFour:

            ScreenFive:

Main.py

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.anchorlayout import AnchorLayout
from kivy.factory import Factory
from kivymd.theming import ThemeManager

from Prelogin.prescreenmanger import PreScreenManager

class MainApp(App):
    pass

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

main.kv

AnchorLayout:
    canvas.before:
        Rectangle:
            size: self.size
            pos: self.pos
            source: "Start/Background.png"   
    anchor_x: 'center'
    anchor_y: 'top'
    Image:
        source: 'Start/Loginlogo.png'
        keep_ratio: False
        allow_stretch: True
        opacity: 1
        size_hint: 1, 0.25
        pos_hint: (0,0)  
    ScreenManager:
        id: screen_manager
        PreScreenManager:
            id: PreScreenManager

这是我所拥有代码的更新版本。 .py文件

from kivy.uix.boxlayout import BoxLayout
from kivy.app import App
from kivy.uix.screenmanager import Screen
from kivy.properties import ObjectProperty
from kivy.lang import Builder

from kivymd.uix.managerswiper import MDSwiperPagination
from kivymd.theming import ThemeManager

Builder.load_file("Prelogin/prescreenmanger.kv")

class MySwiperManager(BoxLayout):
    pass

class PreScreenManager(Screen):
    swiper_manager = ObjectProperty()  # reference to MySwiperManager from kv file

    def do_setup(self, dt):
        # code to do the setup (called after App is instantiated)
        paginator = MDSwiperPagination()
        paginator.screens = self.swiper_manager.screen_names
        paginator.manager = self.swiper_manager
        self.swiper_manager.paginator = paginator
        self.swiper_manager.add_widget(paginator)

.kv文件

<ScreenOne@Screen>:
    name: 'screen one'
    Label: 
        text: 'Hello World'
        color: 1,1,1

<ScreenTwo@Screen>:
    name: 'screen two'


<ScreenThree@Screen>:
    name: 'screen three'


<ScreenFour@Screen>:
    name: 'screen four'


<ScreenFive@Screen>:
    name: 'screen five'


<PreScreenManager>:
    swiper_manager: swiper_manager  # uses the id from below

    MySwiperManager:
        orientation: 'vertical'

        MDSwiperManager:
            id: swiper_manager

            ScreenOne:

            ScreenTwo:

            ScreenThree:

            ScreenFour:

            ScreenFive:

Main.py

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.anchorlayout import AnchorLayout
from kivy.factory import Factory
from kivy.clock import Clock
from kivymd.theming import ThemeManager

from Prelogin.prescreenmanger import PreScreenManager

class MainApp(App):
    theme_cls = ThemeManager()
    theme_cls.primary_palette = 'Indigo'
    def build(self):
        # create an instance of PreScreenManager
        psm = PreScreenManager()

        # schedule the execution of the do_setup() method
        Clock.schedule_once(psm.do_setup)

        # return the PreScreenManager instance as the root of the App display
        return psm

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

main.kv

AnchorLayout:
    canvas.before:
        Rectangle:
            size: self.size
            pos: self.pos
            source: "Start/Background.png"   
    anchor_x: 'center'
    anchor_y: 'top'
    Image:
        source: 'Start/Loginlogo.png'
        keep_ratio: False
        allow_stretch: True
        opacity: 1
        size_hint: 1, 0.25
        pos_hint: (0,0)  
    ScreenManager:
        id: screen_manager
        PreScreenManager:
            id: PreScreenManager

2 个答案:

答案 0 :(得分:1)

我想我几乎可以理解您要做什么。要自动在您的swiper_manager中设置PreScreenManager,请将该属性添加到您的prescreenmanger.kv文件中:

<PreScreenManager>:
    swiper_manager: swiper_manager  # uses the id from below
    my_sm: msm  # uses the id from below

    MySwiperManager:
        orientation: 'vertical'
        id: msm

        MDSwiperManager:
            id: swiper_manager

            ScreenOne:

            ScreenTwo:

            ScreenThree:

            ScreenFour:

            ScreenFive:

我已经自由地将id更改为msm,因为使用类名只会导致混乱。然后,修改您的PreScreenManager类:

class PreScreenManager(Screen):
    swiper_manager = ObjectProperty()  # reference to MDSwiperManager from kv file
    my_sm: ObjectProperty()  # reference to MySwiperManager from kv file

    def do_setup(self, dt):
        # code to do the setup (called after App is instantiated)
        theme_cls = ThemeManager()
        theme_cls.primary_palette = 'Indigo'
        paginator = MDSwiperPagination()
        paginator.screens = self.swiper_manager.screen_names
        paginator.manager = self.swiper_manager
        self.swiper_manager.paginator = paginator
        self.my_sm.add_widget(paginator)

我从没使用过kivyMD,所以我不能保证do_setup()方法内部代码的正确性。最后,通过修改do_setup()类来安排MainApp方法的执行:

class MainApp(App):
    def build(self):
        # create an instance of PreScreenManager
        psm = PreScreenManager()

        # schedule the execution of the do_setup() method
        Clock.schedule_once(psm.do_setup)

        # return the PreScreenManager instance as the root of the App display
        return psm

答案 1 :(得分:0)

swiper_manager = MySwiperManager.ids.swiper_manager

您将类定义(MySwiperManager)与类的实例(例如MySwiperManager())混淆了。通常,您所有的代码都应位于实例级别,将其置于类级别通常是错误的,但这是一个常见错误。

不可能给出具体的解决方案,因为您的示例不完整(实际上,它还有其他一些问题,请始终提供一个最小的 runnable 示例以使事情变得更容易),但一般答案是您要访问ids类实例的MySwiperManager属性。