python - 如何在 KivyMD 中选择目录和文件
问题描述
我正在尝试通过我使用的一个简单应用程序选择一个文件(图片),但每当我单击按钮访问文件(即打开目录)时,我都会file manager
收到此错误消息: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 模块,特别是 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)
有关此库的 API 的更多信息,请点击此处。
我可以给你的一个提示是,因为这个文件选择器在 Windows 平台上非常弱,如果你愿意,我建议使用tkinter
's 。filedialog
推荐阅读
- python - 熊猫,应用字符串连接问题
- python - Replace 方法至少需要两个参数
- java - 使用 mongoTemplate 从数组中获取特定值
- android - SupportLifecycleFragmentImpl 使用谷歌对话框启用位置时自动添加片段
- python - 使用 pandas 查看其他数据帧中是否存在 1 个数据帧的整行
- ruby-on-rails - 用于自连接的嵌套表单和路由助手?
- protocols - 用于 Ultrascale + 的 PROFIBUS 架构:专家意见请求
- excel - 如何禁用工作表上的按钮?
- javascript - 创建高效的早期实例剪辑 WebGL2 顶点着色器
- jquery - 使用关系值搜索数据表