Search code examples
pythonreturnkivyfilechooser

How to display path of selected image as a variable in another method?


I have two methods, get_image_one() opens a Tkinter filechoooser and returns an image which is displayed in a kv file. I want the selected image to be set as the source in method check_for_image() so that further processing can be done on the selected image by check_for_image() for example to check if the image selected by the user has any texts etc. The logic for this testing will be provided by check_for_image()

Please let me know if this is the best way to go about this i.e having two separate methods, one for selecting the file, second for validating the file. Thank you for your time and attention.

Below is my full example.

main.py

from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.core.window import Window
from kivy.uix.popup import Popup
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import ObjectProperty

from tkinter.filedialog import askopenfilename
from tkinter import Tk

class SampBoxLayout(BoxLayout):

    def get_image_one(self):
        '''This method is called by button FileChooser, it opens a FileChooser selects the desired image'''
        Tk().withdraw()
        img1 = askopenfilename(initialdir = "/",title = "Select file",filetypes = (("jpeg files","*.jpg"),("all files","*.*")))
        self.first_image.source = img1

    def check_for_image(self):
        '''This method is called by button TextIdentifier
           1. It needs to get the image selected by the above FileChooser
           2. The selected Image can be analysed further Ex: to check the if the selected image contains any text etc.
        '''
        pass

class SampleApp(App):
    def build(self):
        # Set the background color for the window
        Window.clearcolor = (1, 1, 1, 1)
        return SampBoxLayout()

sample_app = SampleApp()
sample_app.run()

sample.kv

#:kivy 1.10.0
<ColoredBackground@Image>:
    font_size: '48sp'
    color: (.9, .5, .4, 1)
    canvas.before:
        Color:
            rgb: (.2, .9, .9)
        Rectangle:
            pos: self.x + sp(2), self.y + sp(2)
            size: self.width - sp(5), self.height - sp(4)

<SampBoxLayout>:
    first_image: first_image     # <----
    orientation: "vertical"
    padding: 10
    spacing: 10

    # ---------- Button FileChooser ----------
    BoxLayout:
        orientation: "horizontal"
        height: 30

        Button:
            text: "FileChooser"
            on_press: root.get_image_one()
        Button:
            text: "TextIdentifier"
            on_press: root.check_for_image()

    # ---------- Display Images----------
    BoxLayout:
        orientation: "vertical"
        height: 30

        ColoredBackground:
            id: first_image  # <----
            size: self.parent.width, self.parent.height
            allow_stretch: True
            keep_ratio: False

Solution

  • Solution

    1. Replace img1 with self.img1 for accessing image in other method(s).
    2. In get_image_one() method, currently the Kivy App crash when nothing is selected. Therefore, check whether user selected any image. What to do if nothing is selected? e.g. display Popup message.
    3. In check_for_image() method, if all check(s) passed then assign image file to Image's source.

    Recommendations

    If there are many checks then keep it separate. Always keep module small for easy understanding and maintenance.

    Snippet

    class SampBoxLayout(BoxLayout):
    
        def get_image_one(self):
            '''This method is called by button FileChooser, it opens a FileChooser selects the desired image'''
            Tk().withdraw()     # we don't want a full GUI, so keep the root window from appearing
            self.img1 = askopenfilename(initialdir="/", title="Select file",
                                        filetypes=(("jpeg files", "*.jpg"), ("all files", "*.*")))
            if not self.img1:
                # TODO
                # e.g. Kivy Popup message
                print("No image file selected!")
    
        def check_for_image(self):
            '''This method is called by button TextIdentifier
               1. It needs to get the image selected by the above FileChooser
               2. The selected Image can be analysed further Ex: to check the if the selected image contains any text etc.
            '''
            print(self.img1)
            self.first_image.source = self.img1
            self.first_image.reload()
    

    Output

    Img01