pythondrag-and-dropdearpygui

Implementing image drag-and-drop functionality with DearPyGui framework challenged me too much


A few days ago I started learning the DearPyGui framework, got excited with speed and results. However, I encountered challenges when I tried to implement drag-and-drop functionality for images. The usage seems straightforward as the methods add_image and add_image_button have drag_callback and drop_callback parameters, but whatever I tried nothing worked. I searched for the solution in the official documentation but without success - there is not much written about drag-and-drop. I also looked for the ready solutions and found only this that seems for text drag and drop from outside the application and it doesn't address my issue, I need to drag and drop images between elements within the same window.

I am using the most recent DearPyGui 1.11.1 on a Windows machine with Python 3.9.13. The images are created but I can't fire the drag_callback or drop_callback events. For the test I added callback=click_callback parameter to the add_image_button function and it worked. Looks like this method can work, just I am missing something. Below is a simplified variant of my approach - it automatically creates the images to test the code:

import dearpygui.dearpygui as dpg


def get_image(width, height, red, green, blue, alpha):
    """Generates simple image"""
    return [red, green, blue, alpha] * width * height


def drag_callback(sender, app_data):
    print(f"Starting drag from {sender}")  # Never comes here


def drop_callback(sender, app_data):
    print(f"Dropped from {sender}")  # Never comes here


def create_image(image_data, width, height, image_tag, texture_tag):
    with dpg.texture_registry():
        texture_id = dpg.add_static_texture(width, height, image_data, tag=texture_tag)

    # Add the image with drag and drop functionality
    dpg.add_image_button(texture_id, tag=image_tag, payload_type="image_payload", drag_callback=drag_callback,
                         drop_callback=drop_callback)


if __name__ == '__main__':
    dpg.create_context()

    print(f"DPG version {dpg.get_dearpygui_version()}")  # DPG version 1.11.1

    # Create a window
    with dpg.window(label="Image Drag-and-Drop", tag="DragDropWindow", width=800, height=600, no_close=True,
                    no_collapse=True):
        width = 100
        height = 100
        img1 = get_image(width, height, 1, 0, 1, 1)
        img2 = get_image(width, height, 0, 1, 0, 1)
        # Create draggable images with unique tags for both group and texture
        create_image(img1, width, height, "Image1", "ImageTexture1")
        create_image(img2, width, height, "Image2", "ImageTexture2")

    # Setup and show viewport
    dpg.create_viewport(title="Main", width=800, height=600)

    dpg.setup_dearpygui()
    dpg.show_viewport()
    dpg.start_dearpygui()

    # Clean up
    dpg.destroy_context()

Solution

  • finnally found the solution after long hours of internet search.

    you must add these 2 lines :

    def create_image(image_data, width, height, image_tag, texture_tag):
        with dpg.texture_registry():
            texture_id = dpg.add_static_texture(width, height, image_data, tag=texture_tag)
    
        # Add the image with drag and drop functionality
        dpg.add_image_button(texture_id, tag=image_tag, payload_type="image_payload", drag_callback=drag_callback, drop_callback=drop_callback)
    
        # add this to enable drap&drop:
        with dpg.drag_payload(parent=image_tag, drag_data="dragdata", payload_type="image_payload"):
            dpg.add_text("popup drag")