我如何在 KivyMD 中 select 目录和文件
how do I select directories and files in KivyMD
我正在尝试通过我使用 file manager
制作的一个简单应用程序 select 一个文件(图片),但我总是收到此错误消息:kivy.uix.widget.WidgetException: Cannot add <kivymd.uix.filemanager.filemanager.MDFileManager object at 0x000001D98DC5F890>, it already has a parent <kivy.uix.modalview.ModalView object at 0x000001D98DC5F4A0>
,每当我点击在按钮上访问文件(即打开目录)。我不知道我想要的是错的,我什至不知道我做错了什么。
如有任何帮助,我将不胜感激。
这是我的 .py 文件
from kivy.factory import Factory
from kivy.uix.modalview import ModalView
from kivymd.uix.filemanager import MDFileManager
from kivymd.theming import ThemeManager
from kivymd.toast import toast
from kivymd.app import MDApp
from kivy.core.window import Window
Window.size = (300, 530)
class MainApp(MDApp):
title = "File Manage"
def __init__(self, **kwargs):
super().__init__(**kwargs)
Window.bind(on_keyboard=self.events)
self.manager_open = False
self.manager = None
def build(self):
self.theme_cls.primary_palette = 'Gray'
self.theme_cls.primary_hue = '200'
self.theme_cls.theme_style = 'Dark'
return Factory.ExampleFileManager()
def file_manager_open(self):
if not self.manager:
self.manager = ModalView(size_hint=(1, 1), auto_dismiss=False)
self.file_manager = MDFileManager(
exit_manager=self.exit_manager, select_path=self.select_path)
self.manager.add_widget(self.file_manager)
self.file_manager.show('/') # output manager to the screen
self.manager_open = True
self.manager.open()
def select_path(self, path):
'''It will be called when you click on the file name
or the catalog selection button.
:type path: str;
:param path: path to the selected directory or file;
'''
self.exit_manager()
toast(path)
def exit_manager(self, *args):
'''Called when the user reaches the root of the directory tree.'''
self.manager.dismiss()
self.manager_open = False
def events(self, instance, keyboard, keycode, text, modifiers):
'''Called when buttons are pressed on the mobile device..'''
if keyboard in (1001, 27):
if self.manager_open:
self.file_manager.back()
return True
if __name__ == "__main__":
app = MainApp()
app.run()
这是我的 .kv 文件:
<ExampleFileManager@BoxLayout>
orientation: 'vertical'
MDToolbar:
id: progress_toolbar
title: 'Progress'
ScrollView:
MDGridLayout:
cols: 2
adaptive_height: True
spacing: (10, 15)
padding: [25, 25]
MDLabel:
halign: 'center'
text: 'Before'
MDLabel:
halign: 'center'
text: 'Now'
MDCard:
ripple_behavior: True
orientation: 'vertical'
size_hint_y: None
size: 120, 220
elevation: 15
radius: 8
MDIconButton:
icon: "camera-outline"
user_font_size: "64sp"
pos_hint: {"center_x": .5, "center_y": .5}
on_release: app.file_manager_open()
MDCard:
ripple_behavior: True
orientation: 'vertical'
size_hint_y: None
size: 120, 220
elevation: 15
radius: 8
MDIconButton:
icon: "camera-outline"
user_font_size: "64sp"
pos_hint: {"center_x": .5, "center_y": .5}
on_release: app.file_manager_open()
MDTextField:
hint_text: 'Date'
width: 100
MDTextField:
hint_text: 'Date'
width: 100
MDTextField:
hint_text: 'Weight'
width: 80
MDTextField:
hint_text: 'Weight'
width: 80
编辑:
新代码:
from kivy.lang import Builder
from kivymd.app import MDApp
from kivy.core.window import Window
from plyer import filechooser
Window.size = (300, 530)
KV = """
MDBoxLayout:
orientation: 'vertical'
MDToolbar:
id: progress_toolbar
title: 'Progress'
ScrollView:
MDGridLayout:
cols: 2
adaptive_height: True
spacing: (10, 15)
padding: [25, 25]
MDLabel:
halign: 'center'
text: 'Before'
MDLabel:
halign: 'center'
text: 'Now'
MDCard:
ripple_behavior: True
orientation: 'vertical'
size_hint_y: None
size: 120, 220
elevation: 15
radius: 8
MDIconButton:
icon: "camera-outline"
user_font_size: "24sp"
pos_hint: {"center_x": .5, "center_y": .5}
on_release: app.file_chooser1()
Image:
id: img1
allow_stretch: True
keep_ratio: False
# size_hint_y: .5
MDCard:
ripple_behavior: True
orientation: 'vertical'
size_hint_y: None
size: 120, 220
elevation: 15
radius: 8
MDIconButton:
icon: "camera-outline"
user_font_size: "24sp"
pos_hint: {"center_x": .5, "center_y": .5}
on_release: app.file_chooser2()
Image:
id: img2
allow_stretch: True
keep_ratio: False
# size_hint_y: .5
MDTextField:
hint_text: 'Date'
width: 100
MDTextField:
hint_text: 'Date'
width: 100
"""
class Example(MDApp):
def build(self):
return Builder.load_string(KV)
def file_chooser1(self):
filechooser.open_file(on_selection=self.selected1)
def file_chooser2(self):
filechooser.open_file(on_selection=self.selected2)
def selected1(self, selection1):
self.root.ids.img1.source = selection1[0]
def selected2(self, selection2):
self.root.ids.img2.source = selection2[0]
Example().run()
不使用 FileManager
小部件,实际上有一个更好的选择,它来自 plyer module,特别是 filechooser
API。它的作用是打开设备的默认文件管理器应用程序以选择文件夹、文件或保存文件。这是一个例子:
def file_manager_open(self):
from plyer import filechooser
path = filechooser.open_file()[0]
# this method returns a list with the first index
# being the path of the file selected
toast(path)
有关此库 here 的 API 的更多信息。
我可以给你的一个提示是,因为这个文件选择器在 Windows 平台上非常弱,如果你愿意,我建议使用 tkinter
的 filedialog
。
我正在尝试通过我使用 file manager
制作的一个简单应用程序 select 一个文件(图片),但我总是收到此错误消息:kivy.uix.widget.WidgetException: Cannot add <kivymd.uix.filemanager.filemanager.MDFileManager object at 0x000001D98DC5F890>, it already has a parent <kivy.uix.modalview.ModalView object at 0x000001D98DC5F4A0>
,每当我点击在按钮上访问文件(即打开目录)。我不知道我想要的是错的,我什至不知道我做错了什么。
如有任何帮助,我将不胜感激。
这是我的 .py 文件
from kivy.factory import Factory
from kivy.uix.modalview import ModalView
from kivymd.uix.filemanager import MDFileManager
from kivymd.theming import ThemeManager
from kivymd.toast import toast
from kivymd.app import MDApp
from kivy.core.window import Window
Window.size = (300, 530)
class MainApp(MDApp):
title = "File Manage"
def __init__(self, **kwargs):
super().__init__(**kwargs)
Window.bind(on_keyboard=self.events)
self.manager_open = False
self.manager = None
def build(self):
self.theme_cls.primary_palette = 'Gray'
self.theme_cls.primary_hue = '200'
self.theme_cls.theme_style = 'Dark'
return Factory.ExampleFileManager()
def file_manager_open(self):
if not self.manager:
self.manager = ModalView(size_hint=(1, 1), auto_dismiss=False)
self.file_manager = MDFileManager(
exit_manager=self.exit_manager, select_path=self.select_path)
self.manager.add_widget(self.file_manager)
self.file_manager.show('/') # output manager to the screen
self.manager_open = True
self.manager.open()
def select_path(self, path):
'''It will be called when you click on the file name
or the catalog selection button.
:type path: str;
:param path: path to the selected directory or file;
'''
self.exit_manager()
toast(path)
def exit_manager(self, *args):
'''Called when the user reaches the root of the directory tree.'''
self.manager.dismiss()
self.manager_open = False
def events(self, instance, keyboard, keycode, text, modifiers):
'''Called when buttons are pressed on the mobile device..'''
if keyboard in (1001, 27):
if self.manager_open:
self.file_manager.back()
return True
if __name__ == "__main__":
app = MainApp()
app.run()
这是我的 .kv 文件:
<ExampleFileManager@BoxLayout>
orientation: 'vertical'
MDToolbar:
id: progress_toolbar
title: 'Progress'
ScrollView:
MDGridLayout:
cols: 2
adaptive_height: True
spacing: (10, 15)
padding: [25, 25]
MDLabel:
halign: 'center'
text: 'Before'
MDLabel:
halign: 'center'
text: 'Now'
MDCard:
ripple_behavior: True
orientation: 'vertical'
size_hint_y: None
size: 120, 220
elevation: 15
radius: 8
MDIconButton:
icon: "camera-outline"
user_font_size: "64sp"
pos_hint: {"center_x": .5, "center_y": .5}
on_release: app.file_manager_open()
MDCard:
ripple_behavior: True
orientation: 'vertical'
size_hint_y: None
size: 120, 220
elevation: 15
radius: 8
MDIconButton:
icon: "camera-outline"
user_font_size: "64sp"
pos_hint: {"center_x": .5, "center_y": .5}
on_release: app.file_manager_open()
MDTextField:
hint_text: 'Date'
width: 100
MDTextField:
hint_text: 'Date'
width: 100
MDTextField:
hint_text: 'Weight'
width: 80
MDTextField:
hint_text: 'Weight'
width: 80
编辑: 新代码:
from kivy.lang import Builder
from kivymd.app import MDApp
from kivy.core.window import Window
from plyer import filechooser
Window.size = (300, 530)
KV = """
MDBoxLayout:
orientation: 'vertical'
MDToolbar:
id: progress_toolbar
title: 'Progress'
ScrollView:
MDGridLayout:
cols: 2
adaptive_height: True
spacing: (10, 15)
padding: [25, 25]
MDLabel:
halign: 'center'
text: 'Before'
MDLabel:
halign: 'center'
text: 'Now'
MDCard:
ripple_behavior: True
orientation: 'vertical'
size_hint_y: None
size: 120, 220
elevation: 15
radius: 8
MDIconButton:
icon: "camera-outline"
user_font_size: "24sp"
pos_hint: {"center_x": .5, "center_y": .5}
on_release: app.file_chooser1()
Image:
id: img1
allow_stretch: True
keep_ratio: False
# size_hint_y: .5
MDCard:
ripple_behavior: True
orientation: 'vertical'
size_hint_y: None
size: 120, 220
elevation: 15
radius: 8
MDIconButton:
icon: "camera-outline"
user_font_size: "24sp"
pos_hint: {"center_x": .5, "center_y": .5}
on_release: app.file_chooser2()
Image:
id: img2
allow_stretch: True
keep_ratio: False
# size_hint_y: .5
MDTextField:
hint_text: 'Date'
width: 100
MDTextField:
hint_text: 'Date'
width: 100
"""
class Example(MDApp):
def build(self):
return Builder.load_string(KV)
def file_chooser1(self):
filechooser.open_file(on_selection=self.selected1)
def file_chooser2(self):
filechooser.open_file(on_selection=self.selected2)
def selected1(self, selection1):
self.root.ids.img1.source = selection1[0]
def selected2(self, selection2):
self.root.ids.img2.source = selection2[0]
Example().run()
不使用 FileManager
小部件,实际上有一个更好的选择,它来自 plyer module,特别是 filechooser
API。它的作用是打开设备的默认文件管理器应用程序以选择文件夹、文件或保存文件。这是一个例子:
def file_manager_open(self):
from plyer import filechooser
path = filechooser.open_file()[0]
# this method returns a list with the first index
# being the path of the file selected
toast(path)
有关此库 here 的 API 的更多信息。
我可以给你的一个提示是,因为这个文件选择器在 Windows 平台上非常弱,如果你愿意,我建议使用 tkinter
的 filedialog
。