Add Drag and drop import to slicelet?

Hi, is there any way to implement the drag and drop function to a slicelet (qt widget without the main window) as it is with the the main window (hopefully other than rewriting it from scratch ) thanks

Last time I checked you could only implement the drop behavior in C++ by overriding the dropEvent method, but maybe somebody can find a way to do it in Python.

https://doc.qt.io/qt-5/dnd.html

We do not recommend to implement slicelets without main window for many reasons. Slicer now has built-in scripts to strip down the default main window from Python (see here). For more control, you can create a custom application in C++ (based on a default main window that you can customize any way you need).

I came across this thread as I was experimenting adding a custom drop action for a custom app using only python. With the code below I was able to redefine the drop action to execute what I put in dropEvent when I dropped a file path instead of the Slicer default of opening the Add Data Dialog.

class MyClass(qt.QWidget):
    def eventFilter(self, object, event):
        """
        Custom event filter for Slicer Main Window.

        Inputs: Object (QObject), Event (QEvent)
        """
        if event.type() == qt.QEvent.DragEnter:
            self.dragEnterEvent(event)
            return True
        if event.type() == qt.QEvent.Drop:
            self.dropEvent(event)
            return True
        return False
    def dragEnterEvent(self, event):
        """
        Actions to do when a drag enter event occurs in the Main Window.

        Read up on https://doc.qt.io/qt-5.12/dnd.html#dropping
        Input: Event (QEvent)
        """
        if event.mimeData().hasUrls:
            event.acceptProposedAction()  # allows drop event to proceed
        else:
            event.ignore()
    def dropEvent(self, event):
        """
        Actions to do when an item is dropped onto the Main Window.

        Read up on https://doc.qt.io/qt-5.12/dnd.html#dropping
        Input: Event (QEvent)
        """
        print("Custom drop code goes here")

my_class = MyClass()
slicer.util.mainWindow().installEventFilter(my_class)
3 Likes

Thanks for your answer, i did use almost the same process without merging the filters in slicer main window and instead did an override of the qt.QWidget class methods and used it as the main slicelet window.
Instead of eventFilter i had:

class MyClass(qt.QWidget):
    def __init__(self, type, parent=None):
        super(MyClass, self).__init__(parent)
        self.setAcceptDrops(True)

The following functions are the same,

Your approach is great to change the main slicer window drag and drop actions, thank you for pointing it out!

2 Likes