首页 > 解决方案 > Kivy 将视频合并到导航抽屉

问题描述

我已经断断续续地尝试了两个星期来解决这个问题,但没有运气。这是我在编码学习之旅中第一次感到完全陷入困境。非常感谢任何帮助。

现在我的问题是在我的 .kv 文件之外更改屏幕。现在我正在尝试使用:

 class RootScreen(Screen):
    def onNextScreen(self, btn, fileName):
        MDApp.get_running_app().root.current = "ScreenVideo1"
        MDApp.get_running_app().root.ScreenVideo1.test_on_enter(r'C:\file\location' + fileName + '.MOV')  

但这给出了错误代码:

  'RootScreen' object has no attribute 'ScreenVideo1'

主文件

from kivymd.app import MDApp
from kivy.lang import Builder
from kivy.core.window import Window
from kivy.uix.boxlayout import BoxLayout
from kivymd.theming import ThemableBehavior
from kivymd.uix.list import MDList
from kivy.uix.screenmanager import ScreenManager, Screen, NoTransition
from kivy.properties import ObjectProperty
from kivy.uix.videoplayer import VideoPlayer
from kivy.uix.actionbar import ActionBar
from kivy.uix.button import Button
from kivy.core.window import Window

#remove after dev
Window.size = (300,500)

Window.clearcolor = (.976, .980, .996, 1)

screen_helper = r"""
RootScreen:
    MDNavigationLayout:
        ScreenManager:
            id: screen_manager
            ScreenHome:
                id: screen_home
                manager: screen_manager
                name: "Home"
                ScrollView:
                    pos_hint: {'bottom':1}
                    do_scroll_y: True
                    BoxLayout:
                        orientation: 'vertical'
                        padding: 15
                        spacing: 20
                        #size_hint: None, None
                        height: self.minimum_height
                        size_hint: (1, 2)
                        
                        MDToolbar:
                            title: "POTUS"
                            left_action_items:[["menu",lambda x: nav_drawer.set_state("open")]]
                            elevation: 8
                        Widget:
                        
                        StrokeButton:
                            text: "Video Category 1"
                            back_color: (0.576, 0.698, 0.996, 1) if self.state == 'normal' else (0.502, 0, 0.502, .75)
                            on_release: screen_manager.current = "Video1"
         
            ScreenAbout:
                id: screen_about
                manager: screen_manager
                name: "About"
                MDLabel:
                    text: "About"
                BoxLayout:
                    orientation: 'vertical'
                    MDToolbar:
                        title: "POTUS"
                        left_action_items:[["menu",lambda x: nav_drawer.set_state("open")]]
                        elevation: 8
                    Widget:

            ScreenHelp:
                id: screen_help
                manager: screen_manager
                name: "Help"
                MDLabel:
                    text: "Help"
                BoxLayout:
                    orientation: 'vertical'
                    MDToolbar:
                        title: "POTUS"
                        left_action_items:[["menu",lambda x: nav_drawer.set_state("open")]]
                        elevation: 8
                    Widget:

                BoxLayout:
                    orientation: 'vertical'
                    MDToolbar:
                        title: "POTUS"
                        left_action_items:[["menu",lambda x: nav_drawer.set_state("open")]]
                        elevation: 8
                    Widget:

            ScreenVideo1:
                id: screen_video1
                manager: screen_manager
                name: "Video1"
                GridLayout:
                    pos_hint: {'top': 1}
                    cols:1
                    rows:5
                    ActionBar:
                        pos_hint: {'top': 1}
                        height:'100sp'
                        ActionView:
                            ActionPrevious:
                                with_previous: True
                                on_release: screen_manager.current = "Home"
                    
                    StrokeButton:
                        text: " Video option 1"
                        back_color: (0.576, 0.698, 0.996, 1) if self.state == 'normal' else (0.502, 0, 0.502, .75)
                        on_release: root.onNextScreen(self, 'heart')
                    StrokeButton:
                        text: "Video option 2"
                        back_color: (0.576, 0.698, 0.996, 1) if self.state == 'normal' else (0.502, 0, 0.502, .75)
                        on_release:
                    StrokeButton:
                        text: "Video option 3"
                        back_color: (0.576, 0.698, 0.996, 1) if self.state == 'normal' else (0.502, 0, 0.502, .75)
                        on_release:   
    MDNavigationDrawer:
        id: nav_drawer
        BoxLayout: 
            orientation: 'vertical'
            spacing: '8dp'
            padding: '8dp'
                
                MDLabel:
                    text: "blah blah blah"
                    font_style: 'Subtitle1'
                    size_hint_y: None
                    height: self.texture_size[1]
                MDLabel:
                    text: "blah blah blah"
                    font_style: "Caption"
                    size_hint_y: None
                    height: self.texture_size[1]
                ScrollView: 
                    MDList:
                        OneLineIconListItem:
                            on_release:
                                screen_manager.current = "Home"
                            text: 'Home'
                            IconLeftWidget:
                                icon:"folder-home"
                                on_release:
                                    screen_manager.current = "Home"
                        OneLineIconListItem:
                            on_release:
                                screen_manager.current = "Help"
                            text: 'Help'
                            IconLeftWidget:
                                icon:"help-circle-outline"
                                on_release:
                                    screen_manager.current = "Help"
                        OneLineIconListItem:
                            on_release:
                                screen_manager.current = "About"
                            text: 'About'
                            IconLeftWidget:
                                icon: "doctor"
                                on_release:
                                    screen_manager.current = "About"

<StrokeButton@Button>:
    background_color:(0,0,0,0)
    background_normal:''
    back_color:(1,0,1,1)
    border_radius: 18
    color: self.back_color
    bold: True
    canvas.before:
        Color:
            rgba: self.back_color
        Line:
            rounded_rectangle: (self.pos[0],self.pos[1],self.size[0],self.size[1],self.border_radius)
            width: 1.2
"""

class RootScreen(Screen):
    def onNextScreen(self, btn, fileName):
        MDApp.get_running_app().root.current = "ScreenVideo1"
        MDApp.get_running_app().root.ScreenVideo1.test_on_enter(r'C:\file\location' + fileName + '.MOV')

class ScreenHome(Screen):
    pass

class ScreenAbout(Screen):
    pass

class ScreenHelp(Screen):
    pass

class ScreenVideo1(Screen):
    def test_on_enter(self, vidname):
        #self.add_widget(Button(text="Back"))
        self.vid = VideoPlayer(source=vidname, state='play',
                               options={'allow_stretch':True,
                                        'eos': 'loop'})
        self.add_widget(self.vid)

    def on_leave(self):
        pass

    def onBackBtn(self):
        self.vid.state = 'stop'
        self.remove_widget(self.vid)
        MDApp.get_running_app().root.current = "ScreenVideo1"
        
class DemoApp(MDApp):
    def build(self):
        screen = Builder.load_string(screen_helper)
        return screen


DemoApp().run()

当我使用 Manager 构建我的应用程序时,它曾经非常容易

class Manager(ScreenManager):
    transition = NoTransition()
    screen_one = ObjectProperty(None)
    screen_two = ObjectProperty(None)
    screen_home = ObjectProperty(None)
    

    def __init__(self, *args, **kwargs):
        super(Manager, self).__init__(*args, **kwargs)
        # list to keep track of screens we were in
        self.list_of_prev_screens = []

class ScreensApp(MDApp):
    def build(self):
        return Manager()

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

然后我会使用管理器更改屏幕。但是现在我正在使用导航抽屉,我无法再使用管理器构建我的应用程序。

class ScreenOne(Screen):
    def onNextScreen(self, btn, fileName):
        self.manager.list_of_prev_screens.append(btn.parent.name)
        self.manager.current = 'screen2'
        self.manager.screen_two.test_on_enter(r'C:\file\location' + fileName + '.MOV')

标签: pythonkivy

解决方案


你的代码:

class RootScreen(Screen):
    def onNextScreen(self, btn, fileName):
        MDApp.get_running_app().root.current = "ScreenVideo1"
        MDApp.get_running_app().root.ScreenVideo1.test_on_enter(r'C:\file\location' + fileName + '.MOV')

试图将 的根小部件App视为 a ScreenManager,但不是,它是 a RootScreen。因此,您需要访问ScreenManager,如下所示:

class RootScreen(Screen):
    def onNextScreen(self, btn, fileName):
        MDApp.get_running_app().root.ids.screen_manager.current = "Video1"
        MDApp.get_running_app().root.ids.screen_manager.current_screen.test_on_enter(r'C:\file\location' + fileName + '.MOV')

推荐阅读