如何使用带有Kivy的FileChooser选择多个文件?

时间:2018-07-11 22:25:59

标签: python python-3.x kivy

我正在使用kivy和python来构建应用程序。

我正在尝试构建一个应用程序,在其中可以选择几张图像,将它们添加到一个数组中,然后通过另一种缝合图像的方法(使用缝制器类)将该图像数组传递。输出图像将显示在三个屏幕之一上(我也想删除中间屏幕)。

因此,从本质上讲,我想要帮助的是如何使用kivy中的filechooser选择多个文件,然后将这些文件添加到数组中,以便以后可以通过其他方法进行传递。

借助this post中@ikolim的帮助,我已经能够创建该应用程序。

main.py

from kivy.app import App
from kivy.uix.tabbedpanel import TabbedPanel
from kivy.properties import ObjectProperty
from PIL import Image


class RootWidget(TabbedPanel):
    manager = ObjectProperty(None)
    img = ObjectProperty(None)
    img3 = ObjectProperty(None)
    img4 = ObjectProperty(None)
    lab = ObjectProperty(None)

    def on_touch_up(self, touch):
        if not self.img3.collide_point(*touch.pos):
            return True
        else:
            self.lab.text = 'Pos: (%d,%d)' % (touch.x, touch.y)
            return True

    def switch_to(self, header):
        # set the Screen manager to load  the appropriate screen
        # linked to the tab head instead of loading content
        self.manager.current = header.screen

        # we have to replace the functionality of the original switch_to
        self.current_tab.state = "normal"
        header.state = 'down'
        self._current_tab = header

    def select_to(self, *args):
        try:
            print(args[1][0])
            iw = Image.open(args[1][0])
            iw.save('./phase.jpg')
            gray = iw.convert('1')
            gray.save('./gray_im.jpg')
            self.img3.source = './gray_im.jpg'
            self.img4.source = './gray_im.jpg'
            self.img.source = './phase.jpg'
            self.img.reload()
            self.img3.reload()
            self.img4.reload()
        except:
            pass

    def update_touch_label(self, label, touch):
        label.text = 'Pos:(%d, %d)' % (touch.x, touch.y)
        label.texture_update()
        label.pos = touch.pos
        label.size = label.texture_size[0] + 20, label.texture_size[1] + 20


class TestApp(App):
    title = 'Screen Widget'

    def build(self):
        return RootWidget()

    def on_pause(self):
        return True


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

Test.kv

#:kivy 1.10.1

<RootWidget>:
    manager: manager
    img: img
    img3: img3
    img4: img4
    lab: lab
    do_default_tab: False

    ScreenManager:
        id: manager

        Screen:
            id: sc1
            name:'Load img'

            FileChooserIconView:
                canvas.before:
                    Color:
                        rgb: 0.5, 0.4, 0.5
                    Rectangle:
                        pos: self.pos
                        size: self.size
                on_selection:
                    root.select_to(*args)

        Screen:
            id: sc2
            name: 'Image'

            FloatLayout:
                Button:
                    id: lab
                    pos_hint: {"right": 0.55, 'top': 1}
                    size_hint: .15,0.1

            RelativeLayout:
                Image:
                    id: img
                    on_touch_down:
                        str('Relative:{}'.format(args[1].pos))
                    pos_hint: {"left": 1, 'bottom': 1}
                    size_hint: 0.5, 1
                    allow_stretch: True

            RelativeLayout:
                Image:
                    id: img3
                    pos_hint: {"right": 1, 'bottom': 1}
                    size_hint: 0.5, 1
                    allow_stretch: True

        Screen:
            id: sc3
            name: 'Image_'

            FloatLayout:
                Image:
                    id: img4
                    keep_data: True
                    post: self.pos
                    size: self.size

    TabbedPanelHeader:
        text: sc1.name
        background_color: 1, 0, 0, 1
        screen: sc1.name

    TabbedPanelHeader:
        text: sc2.name
        background_color: 1, 1, 0, 1
        screen: sc2.name

    TabbedPanelHeader:
        text: sc3.name
        background_color: 1, 0, 1, 1
        screen: sc3.name

2 个答案:

答案 0 :(得分:1)

以下是一个可以满足我的要求的示例:

import os

import kivy
from kivy import platform
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.floatlayout import FloatLayout
import kivy.garden.filebrowser


class FileBrowserApp(App):

    def build(self):
        self.root = FloatLayout()
        button = Button(text='Select Files', pos_hint={'x':0, 'y': 0}, size_hint=(0.2, 0.1))
        button.bind(on_press=self.do_select)
        self.root.add_widget(button)
        return self.root

    def do_select(self, *args):
        homeDir = None
        if platform == 'win':
            homeDir = os.environ["HOMEPATH"]
        elif platform == 'android':
            homeDir = os.path.dirname(os.path.abspath(__file__))
        elif platform == 'linux':
            homeDir = os.environ["HOME"]
        self.fbrowser = kivy.garden.filebrowser.FileBrowser(select_string='Select',
            multiselect=True, filters=['*.png'], path=homeDir)
        self.root.add_widget(self.fbrowser)
        self.fbrowser.bind(
            on_success=self._fbrowser_success,
            on_canceled=self._fbrowser_canceled,
            on_submit=self._fbrowser_success)

    def _fbrowser_success(self, fbInstance):
        if len(fbInstance.selection) == 0:
            return
        selected = []
        for file in fbInstance.selection:
            selected.append(os.path.join(fbInstance.path, file))
        print('selected: ' + str(selected))
        self.root.remove_widget(self.fbrowser)
        self.fbrowser = None

    def _fbrowser_canceled(self, instance):
        self.root.remove_widget(self.fbrowser)
        self.fbrowser = None

if __name__=="__main__":
    app = FileBrowserApp()
    app.run()

答案 1 :(得分:0)

在您的Test.kv文件中,在FileChooserIconView之后:添加多选:True

FileChooserIconView:
    multiselect: True

这将允许选择多个文件。

如果使用FileChooserListView而不是FileChooserIconView,则文件选择器窗口将不会在视觉上区分选定/未选定的文件。您仍然可以选择多个文件,但是您需要记住所选的文件。第一次单击选择,第二次单击取消选择。希望该小部件的开发人员能尽快解决此问题。