简体   繁体   中英

Mimic Tkinter file open in Kivy

I have worked mostly with Tkinter before and I used the following code to store path of file I selected. After exploring Kivy, it doesn't seem like Kivy have a simple function like this. So I tried using the filechoser instead

path = filedialog.askopenfilename(initialdir="/", title="Select file")

Main code is very simple

class checker_ui(GridLayout):
    def findreport(self,path):
        pass



class Checker(App):
    def build(self):
        return checker_ui()

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

Then I created a .kv file just to see what filechooser looks like. The script would just open and freeze.

<checker_ui>:
    BoxLayout:
        FileChooserIconLayout:
            id:filechooser
            on_selection:root.select(*args)

Here is the output

冻结

I search all over the place and did not see anyone with a similar issue. Is there an alternative I can try to mimic the tkinter behaviour or am I stuck with this issue? I'm on a Windows machine and normal kivy widget works, ie: button,label etc.

so I wrote a lot more code than you (based heavily on the kivy example @ https://kivy.org/docs/api-kivy.uix.filechooser.html#usage-example )

from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.factory import Factory
from kivy.properties import ObjectProperty
from kivy.uix.popup import Popup
from kivy.lang import Builder

Builder.load_string("""
#:kivy 1.1.0

<Root>:
    text_input: text_input

    BoxLayout:
        orientation: 'vertical'
        BoxLayout:
            size_hint_y: None
            height: 30
            Button:
                text: 'Load'
                on_release: root.show_load()
            Button:
                text: 'Save'
                on_release: root.show_save()

        BoxLayout:
            TextInput:
                id: text_input
                text: ''

            RstDocument:
                text: text_input.text
                show_errors: True

<LoadDialog>:
    BoxLayout:
        size: root.size
        pos: root.pos
        orientation: "vertical"
        FileChooserListView:
            id: filechooser

        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)

<SaveDialog>:
    text_input: text_input
    BoxLayout:
        size: root.size
        pos: root.pos
        orientation: "vertical"
        FileChooserListView:
            id: filechooser
            on_selection: text_input.text = self.selection and self.selection[0] or ''

        TextInput:
            id: text_input
            size_hint_y: None
            height: 30
            multiline: False

        BoxLayout:
            size_hint_y: None
            height: 30
            Button:
                text: "Cancel"
                on_release: root.cancel()

            Button:
                text: "Save"
                on_release: root.save(filechooser.path, text_input.text)""")
import os


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


class SaveDialog(FloatLayout):
    save = ObjectProperty(None)
    text_input = ObjectProperty(None)
    cancel = ObjectProperty(None)


class Root(FloatLayout):
    loadfile = ObjectProperty(None)
    savefile = ObjectProperty(None)
    text_input = ObjectProperty(None)

    def dismiss_popup(self):
        self._popup.dismiss()

    def show_load(self):
        content = LoadDialog(load=self.load, cancel=self.dismiss_popup)
        self._popup = Popup(title="Load file", content=content,
                            size_hint=(0.9, 0.9))
        self._popup.open()

    def show_save(self):
        content = SaveDialog(save=self.save, cancel=self.dismiss_popup)
        self._popup = Popup(title="Save file", content=content,
                            size_hint=(0.9, 0.9))
        self._popup.open()

    def load(self, path, filename):
        with open(os.path.join(path, filename[0])) as stream:
            self.text_input.text = stream.read()

        self.dismiss_popup()

    def save(self, path, filename):
        with open(os.path.join(path, filename), 'w') as stream:
            stream.write(self.text_input.text)

        self.dismiss_popup()


class Editor(App):
    def build(self):
        return Root()




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

Solution

  1. Replace FileChooserIconLayout with FileChooserIconView
  2. Add a BoxLayout and make FileChooserIconView a children of the BoxLayout

Example

main.py

from kivy.app import App
from kivy.uix.gridlayout import GridLayout


class Checker_ui(GridLayout):

    def findreport(self, path):
        print("path=", path)


class Checker(App):

    def build(self):
        return Checker_ui()


if __name__ == "__main__":
    Checker().run()

checker.kv

#:kivy 1.10.0

<Checker_ui>:
    BoxLayout:
        size: root.size
        pos: root.pos
        orientation: "vertical"
        FileChooserIconView:
            id: filechooser
            on_selection: root.select(*args)

Output

Img01-AppStartup

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM