【问题标题】:Kivy Inherit ScreenManager from FloatLayoutKivy 从 FloatLayout 继承 ScreenManager
【发布时间】:2022-01-18 03:46:41
【问题描述】:

我无法理解如何使用 Kivy 将一个类的功能继承到另一个类中。我了解错误消息 ('LoadDialog_Directory' object has no attribute 'manager'),但我只是不知道如何修复它。我相信我需要对下面的函数做点什么,但最终我不知道。

def __init__(self, **kwargs):
        super().__init__(**kwargs)

此脚本的目标是能够为filechooser 选择特定驱动程序作为path。我选择this method 与其他人相比,因为大多数人使用的是 Kivy 1.11.1,这个版本有很多不推荐使用的功能,不适用于 2.0。

.py

from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.lang.builder import Builder
from kivy.uix.spinner import SpinnerOption
from kivy.uix.popup import Popup
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.floatlayout import FloatLayout
from kivy.properties import ObjectProperty
from kivy.utils import platform
from kivy.properties import StringProperty

import os
import string


class WindowManager(ScreenManager):
    pass   
class MyOption(SpinnerOption):
    pass


class LoadDialog_Directory(FloatLayout):
    load = ObjectProperty(None)
    cancel = ObjectProperty(None)

    def dir_driver(self):
        x = self.manager.get_screen("first")
        return str(x.ids.drive_dir.text)

        
        
class FirstWindow(Screen):

    def get_drives(self):
        drives = ['%s:' % d for d in string.ascii_uppercase if os.path.exists('%s:' % d)]
        return drives
        
      
    def dismiss_popup(self):
        self._popup.dismiss()
  
        
    def show_load_directory(self):
        content = LoadDialog_Directory(load=self.directroy_path, cancel=self.dismiss_popup)
        self._popup = Popup(title="Load file", content=content, size_hint=(0.9, 0.9))
        self._popup.open()
        
                
    def directroy_path(self, path, filename):        
        self.ids.text_input_directory.text = str(filename[0])
        self.dismiss_popup()
        
             
kv_main = Builder.load_file('main.kv')

#
class MyApp(App):
    def build(self):
        return kv_main
        

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

ma​​in.kv

#:include first.kv

WindowManager:
    FirstWindow:
    
<LoadDialog_Directory>:
    BoxLayout:
        size: root.size
        pos: root.pos
        orientation: "vertical"
        FileChooserListView:
            id: filechooser
            dirselect: True
            path: root.dir_driver()

        BoxLayout:
            size_hint_y: None
            height: 30
            Button:
                text: "Cancel"
                on_release: root.cancel()
            Button:
                text: "Load"
                on_release: root.load(filechooser.path, filechooser.selection)

first.kv

<FirstWindow>
    name: 'first'
    GridLayout:
        cols: 1
        
        BoxLayout:
            orientation: "horizontal"               
            TextInput:
        
        BoxLayout:
            orientation: "horizontal"
            Spinner:    
                id: drive_dir
                text: "Root Drive"
                halign: 'center'
                option_cls: "MyOption"
                values: root.get_drives()               
            Button:
                text: "Set Result Directory"
                on_release: root.show_load_directory()
            TextInput:
                id: text_input_directory
                disabled: True
                text: text_input_directory.text
        
        BoxLayout:
            size_hint: (0.01, 1)
            orientation: "horizontal"       
            TextInput:

旁注:额外空白TextInput 的原因是因为如果占用太多应用程序,Spinner 将无法运行(显示驱动程序)。

【问题讨论】:

    标签: python inheritance kivy


    【解决方案1】:

    经过几个小时的反复试验,我终于让它工作了,但我不知道它为什么工作。以下是变化:

    1. class LoadDialog_Directory(FloatLayout) 中的新变量 - input_pth
    2. class FirstWindow(Screen) 函数show_load_directory(self) 中将input_pth 调用到我的content 变量中
    3. 在 main.kv 文件中将我的 filechooser.path 设置为 root.input_pth

    我不明白content 中的input_pth 变量如何能够引用class LoadDialog_Directory(FloatLayout) 而无需传递类似的内容:

    def __init__(self, input_pth, **kwargs):
            super(LoadDialog_Directory, self).__init__()
            self.input_pth = input_pth
    

    .py

    from kivy.app import App
    from kivy.uix.screenmanager import ScreenManager, Screen
    from kivy.lang.builder import Builder
    from kivy.uix.spinner import SpinnerOption
    from kivy.uix.popup import Popup
    from kivy.uix.button import Button
    from kivy.uix.boxlayout import BoxLayout
    from kivy.uix.floatlayout import FloatLayout
    from kivy.properties import ObjectProperty
    from kivy.utils import platform
    from kivy.properties import StringProperty
    
    import os
    import string
    
    
    class WindowManager(ScreenManager):
        pass  
        
    class MyOption(SpinnerOption):
        pass
    
    
    class LoadDialog_Directory(FloatLayout):   
        input_pth = StringProperty()
        load = ObjectProperty()
        cancel = ObjectProperty()
        
            
            
    class FirstWindow(Screen):
    
        def drive_list(self):
            drives = ['%s:' % d for d in string.ascii_uppercase if os.path.exists('%s:' % d)]
            return drives
            
          
        def dismiss_popup(self):
            self._popup.dismiss()
      
            
        def show_load_directory(self):
            content = LoadDialog_Directory(load=self.directroy_path, cancel=self.dismiss_popup, input_pth=self.ids.drive_dir.text)
            
            self._popup = Popup(title="Load file", content=content, size_hint=(0.9, 0.9))
            self._popup.open()
            
                    
        def directroy_path(self, path, filename):        
            self.ids.text_input_directory.text = str(filename[0])
            self.dismiss_popup()
    
            
                 
    kv_main = Builder.load_file('main.kv')
    
    #
    class MyApp(App):
        def build(self):
            return kv_main
            
    
    if __name__ == '__main__':
        
        MyApp().run()
    

    ma​​in.kv

    #:include first.kv
    
    WindowManager:
        FirstWindow:
        
    <LoadDialog_Directory>:
        BoxLayout:
            size: root.size
            pos: root.pos
            orientation: "vertical"
            FileChooserListView:
                id: filechooser
                dirselect: True
                path: root.input_pth
    
            BoxLayout:
                size_hint_y: None
                height: 30
                Button:
                    text: "Cancel"
                    on_release: root.cancel()
                Button:
                    text: "Load"
                    on_release: root.load(filechooser.path, filechooser.selection)
    

    first.kv

    <FirstWindow>
        name: 'first'
        GridLayout:
            cols: 1
            
            BoxLayout:
                orientation: "horizontal"               
                TextInput:
            
            BoxLayout:
                orientation: "horizontal"
                Spinner:    
                    id: drive_dir
                    halign: 'center'
                    option_cls: "MyOption"
                    values: root.drive_list()
    
                Button:
                    text: "Set Result Directory"
                    on_release: root.show_load_directory()
                TextInput:
                    id: text_input_directory
                    disabled: True
                    text: text_input_directory.text
            
            BoxLayout:
                size_hint: (0.01, 1)
                orientation: "horizontal"       
                TextInput:
    

    【讨论】:

      猜你喜欢
      • 2018-08-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多