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

2022-01-15 00:00:00 python python-3.x kivy

问题描述

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

I am using kivy and python to build an application.

我正在尝试构建一个应用程序,我可以在其中选择多个图像,将它们添加到一个数组中,然后通过另一个拼接图像的方法(使用stitcher 类)传递这个图像数组.输出图像将显示在三个屏幕之一(我也想移除中间屏幕).

I am trying to build an application in which I can select several images, add them to an array, and then pass this array of images through another method which stitches the images (using the stitcher class). The output image will display on one of the three screens (also I want to remove the middle screen).

所以本质上我想要帮助的是如何能够在 kivy 中使用 filechooser 选择多个文件,然后将这些文件添加到我以后可以通过不同方法传递的数组中.

So essentially what I would like help with is how to be able to select multiple files with filechooser in kivy and then add these files to array that I can later pass through a different method.

在 这篇文章,我已经可以创建应用了.

With the help of @ikolim in this post, I have been able to create the application.

ma​​in.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


解决方案

这是一个我认为你想要的例子:

Here is an example that does what I think you want:

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()

相关文章