2

I'm new to kivy and I'm trying to create a drag and drop app where if the image is dropped onto the gridlayout the image is shown on the app as shown below. I'm trying to get the file_path of the image and then using the file_path to display it on the gridlayout but unfortunately, that is not working. Any help would be greatly appreciated!

This is the current image enter image description here

This is what I want after dragging the image enter image description here

Kv file

# Custom button
<CustButton@Button>:
    font_size: 32
    background_normal: 'Colour_yellow.png'
    background_down: 'Colour_blue.png'

<Cust2@Button>:
    font_size: 32
    background_normal: 'Colour_red.png'
    background_down: 'Colour_blue.png'

<Cust3@Button>:
    font_size: 32
    background_normal: 'Colour_white.png'
    background_down: 'Colour_blue.png'

<Cust4@Button>:
    font_size: 32
    background_normal: 'Colour_blue.png'
    background_down: 'Colour_white.png'

<CalcGridLayout>:
    id: calculator
    display: entry
    rows: 5
    padding: 10
    spacing: 10

    BoxLayout:
        spacing: 100
        size_hint: .5, None
        Cust2:
            text: "Whats the intensity you want?"

    BoxLayout:

        size_hint: .5, None
        TextInput:
            id: entry
            font_size: 70
            multiline: False
            hint_text: "Type here"

    BoxLayout:
        spacing: 100
        size_hint: .5, None
        Cust4:
            text: "Drag and Drop picture below:"
            on_release: root.build1()

    #THIS IS WHERE I'M STUCK ON
    BoxLayout:
        Image:
            source: root._on_file_drop(file_path)

    BoxLayout:
        size_hint: 1, .3
        spacing: 10

        CustButton:
            text: "Click here for \n reduced size"

        CustButton:
            text: "Click here for pos \n  and intensity of \n      each pixel"
            on_release: root.reduced_image()

        CustButton:
            text: "Click here \n for graph"

        CustButton:
            text: "Click here \n     for all"

        CustButton:
            text: "Extra"

Python file

import kivy

kivy.require("1.9.0")

from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.core.window import Window
Window.clearcolor = (0.5, 0.5, 0.5, 1)


class CalcGridLayout(GridLayout):

    def reduced_image(self):
    #ignore

    def build1(self):
        Window.bind(on_dropfile=self._on_file_drop)
        return

    def _on_file_drop(self, window, file_path):
        print(file_path)
        return file_path



class dropdownApp(App):

    def build(self):
        return CalcGridLayout()


dropApp = dropdownApp()
dropApp.run()
Abid Abdul Gafoor
  • 462
  • 1
  • 6
  • 18

1 Answers1

5

Solution

Please refer to the snippets, and complete example for details.

kv file

  1. Remove on_release: root.build1()
  2. Replace source: root._on_file_drop(file_path) with id: img

Snippet

BoxLayout:
    spacing: 100
    size_hint: .5, None
    Cust4:
        text: "Drag and Drop picture below:"

BoxLayout:
    Image:
        id: img

Python Code

  1. Add import statement, from kivy.properties import StringProperty
  2. Declare property, filePath = StringProperty('') in class CalcGridLayout().
  3. Add constructor to class CalcGridLayout() and move Window.bind(on_dropfile=self._on_file_drop) from build1() method
  4. Remove build1() method
  5. In _on_file_drop() method, replace return file_path with self.filePath = file_path.decode("utf-8") self.ids.img.source = self.filePath and self.ids.img.reload()

Snippet

from kivy.properties import StringProperty
...

class CalcGridLayout(GridLayout):
    filePath = StringProperty('')

    def __init__(self, **kwargs):
        super(CalcGridLayout, self).__init__(**kwargs)
        Window.bind(on_dropfile=self._on_file_drop)

    def reduced_image(self):
        print(self.filePath)

    def _on_file_drop(self, window, file_path):
        print(file_path)
        self.filePath = file_path.decode("utf-8")     # convert byte to string
        self.ids.img.source = self.filePath
        self.ids.img.reload()   # reload image

Window » on_dropfile Event

on_dropfile(filename)

Event called when a file is dropped on the application.

Warning

This event currently works with sdl2 window provider, on pygame window provider and OS X with a patched version of pygame. This event is left in place for further evolution (ios, android etc.)

Example

main.py

import kivy
kivy.require("1.11.0")

from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.core.window import Window
from kivy.properties import StringProperty

Window.clearcolor = (0.5, 0.5, 0.5, 1)


class CalcGridLayout(GridLayout):
    filePath = StringProperty('')

    def __init__(self, **kwargs):
        super(CalcGridLayout, self).__init__(**kwargs)
        Window.bind(on_dropfile=self._on_file_drop)

    def reduced_image(self):
        print(self.filePath)

    def _on_file_drop(self, window, file_path):
        print(file_path)
        self.filePath = file_path.decode("utf-8")     # convert byte to string
        self.ids.img.source = self.filePath
        self.ids.img.reload()   # reload image


class DragDropApp(App):

    def build(self):
        return CalcGridLayout()


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

dragdrop.kv

#:kivy 1.11.0

# Custom button
<CustButton@Button>:
    background_normal: "/home/iam/Pictures/AppImages/Colors/yellow.png"   # 'Colour_yellow.png'
    background_down: "/home/iam/Pictures/AppImages/Colors/blue.png"       # 'Colour_blue.png'
    text_size: self.size
    halign: 'center'
    valign: 'middle'

<Cust2@Button>:
    font_size: 32
    background_normal: "/home/iam/Pictures/AppImages/Colors/red.png"   # 'Colour_red.png'
    background_down: "/home/iam/Pictures/AppImages/Colors/blue.png"     # 'Colour_blue.png'

<Cust3@Button>:
    font_size: 32
    background_normal: "/home/iam/Pictures/AppImages/Colors/white.png"     # 'Colour_white.png'
    background_down: "/home/iam/Pictures/AppImages/Colors/blue.png"       # 'Colour_blue.png'

<Cust4@Button>:
    font_size: 32
    background_normal: "/home/iam/Pictures/AppImages/Colors/blue.png"     # 'Colour_blue.png'
    background_down: "/home/iam/Pictures/AppImages/Colors/white.png"       # 'Colour_white.png'

<CalcGridLayout>:
    id: calculator
    display: entry
    rows: 5
    padding: 10
    spacing: 10

    BoxLayout:
        spacing: 100
        size_hint: .5, None
        Cust2:
            text: "Whats the intensity you want?"

    BoxLayout:
        size_hint: .5, None
        TextInput:
            id: entry
            font_size: 70
            multiline: False
            hint_text: "Type here"

    BoxLayout:
        spacing: 100
        size_hint: .5, None
        Cust4:
            text: "Drag and Drop picture below:"

    BoxLayout:
        Image:
            id: img

    BoxLayout:
        size_hint: 1, .3
        spacing: 10

        CustButton:
            text: "Click here for \n reduced size"

        CustButton:
            text: "Click here for pos \n  and intensity of \n      each pixel"
            on_release: root.reduced_image()

        CustButton:
            text: "Click here \n for graph"

        CustButton:
            text: "Click here \n     for all"

        CustButton:
            text: "Extra"

Output

Img01 Img02

ikolim
  • 15,721
  • 2
  • 19
  • 29
  • Thank you so much! How would I be able to use the filepath in the other function `def reduced_image(self):`? – Abid Abdul Gafoor Jul 25 '18 at 06:59
  • @AbidAbdulGafoor: Please refer to my updated post for saving and accessing `file_path`. Please remember to mark the answer as accepted, and/or vote on the answer. Thank you. – ikolim Jul 25 '18 at 13:41