Drag-and-drop from custom QT window into Viewport

897 views
Skip to first unread message

Alec Fredericks

unread,
Nov 9, 2016, 12:21:52 PM11/9/16
to Python Programming for Autodesk Maya
Hi there,
I think I'm misunderstanding something fundamental about QT and Maya UI interactions.
I've created a small PyQt window that contains some tabs and, in one of my test tabs, I have a grid populated by a couple of custom QLabel widgets.
Those widgets are the bits I want to drag into the Maya viewport and, in turn, execute some code when the drop is recognized.

In my custom QLabel, I have a dragEnterEvent and mousePressEvent.

For the main Maya window, I install an eventFilter that checks for QEvent.Enter, DragEnter and Drop.

The eventFilter only ever seems to fire off the QEvent.Enter code but never DragEnter or Drop.

Here's my eventFilter:

    def eventFilter(self, receiver, event):
        self.receiver = receiver
        
        if event.type() is QEvent.Enter:
            print("ENTERED, FOOL!")
            self.mouse_button = QApplication.mouseButtons()
            event.accept()
            return True
            
        if event.type() is QEvent.DragEnter:
            print("DRAG ENTERED!")
            self.mouse_button = QApplication.mouseButtons()
            event.accept()
            return True
            
        if event.type() is QEvent.Drop:
            print("DROPPED")
            library_w = event.source()
            if self.mouse_button == Qt.LeftButton:
                print 'you dropped the bomb.'
                return True
            else:
                print 'nothing dropped.'

Is there something more I need to do to get DragEnter and Drop to function in the eventFilter?

Thanks,
Alec


Justin Israel

unread,
Nov 9, 2016, 3:29:14 PM11/9/16
to python_in...@googlegroups.com
On Thu, Nov 10, 2016 at 6:21 AM Alec Fredericks <alec.fr...@gmail.com> wrote:
Hi there,
I think I'm misunderstanding something fundamental about QT and Maya UI interactions.
I've created a small PyQt window that contains some tabs and, in one of my test tabs, I have a grid populated by a couple of custom QLabel widgets.
Those widgets are the bits I want to drag into the Maya viewport and, in turn, execute some code when the drop is recognized.

In my custom QLabel, I have a dragEnterEvent and mousePressEvent.

For the main Maya window, I install an eventFilter that checks for QEvent.Enter, DragEnter and Drop.

The eventFilter only ever seems to fire off the QEvent.Enter code but never DragEnter or Drop.

I would try not accepting the event + returning True in your block that handles QEvent.Enter. That indicates that you want to swallow the event and the viewport will never see it it to do any custom handling. Does it start working when you ditch that block or at least just return False? I have viewport code that looks similar to your DragEnter and Drop blocks. 

Also, your source label widgets shouldn't need a dragEnterEvent defined on them. That is for the case where they want to accept things dropped on them.
 

Here's my eventFilter:

    def eventFilter(self, receiver, event):
        self.receiver = receiver
        
        if event.type() is QEvent.Enter:
            print("ENTERED, FOOL!")
            self.mouse_button = QApplication.mouseButtons()
            event.accept()
            return True
            
        if event.type() is QEvent.DragEnter:
            print("DRAG ENTERED!")
            self.mouse_button = QApplication.mouseButtons()
            event.accept()
            return True
            
        if event.type() is QEvent.Drop:
            print("DROPPED")
            library_w = event.source()
            if self.mouse_button == Qt.LeftButton:
                print 'you dropped the bomb.'
                return True
            else:
                print 'nothing dropped.'

Is there something more I need to do to get DragEnter and Drop to function in the eventFilter?

Thanks,
Alec


--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/python_inside_maya/4565ad58-3009-4ef6-a9ae-3a28e390aab2%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Alec Fredericks

unread,
Nov 12, 2016, 4:09:21 PM11/12/16
to Python Programming for Autodesk Maya
Thanks for the reply, Justin.
Oddly -- or maybe not, based on my code -- the drag-and-drop eventFilter still doesn't seem to recognize either DragEnter or Drop.

If anyone has a chance to look at this chunk of code that I ripped out of the rest of my code to simplify things, it's much appreciated. If I'm missing something fundamental, it would be great to know that, too.
I've cobbled things together from disparate corners of the web, so maybe I'm just not seeing something important.

import maya.cmds as mc
import maya.mel as mm
import maya.OpenMayaUI as omui
from Qt.QtCore import *
from Qt.QtGui import *
from Qt.QtWidgets import *
from maya.app.general.mayaMixin import MayaQWidgetBaseMixin, MayaQWidgetDockableMixin
from shiboken2 import wrapInstance
import os
import sys
from pprint import pprint

# set global values for the main window

def getMayaWindow():
    mayaMainWindowPtr = omui.MQtUtil.mainWindow()
    return wrapInstance(long(mayaMainWindowPtr), QWidget)

class MainWindowFilter(QObject):
    def eventFilter(self, receiver, event):
        self.receiver = receiver
        """
        if event.type() is QEvent.Enter:
            print("ENTER EVENT, FOOL!")
            self.mouse_button = QApplication.mouseButtons()
            #event.accept()
            return False
        """    
        if event.type() is QEvent.DragEnter:
            print("DRAG ENTERED!")
            event.accept()
            
            """
            if e.mimeData().hasFormat('text/plain'):
                event.accept()
            else:
                event.ignore() 
            """
            
        if event.type() is QEvent.Drop:
            print("DROPPED")
            library_w = event.source()
            if self.mouse_button == Qt.LeftButton:
                print 'you dropped the bomb.'
            else:
                print 'nothing dropped.'
                
        return False
        
global filter
filter = MainWindowFilter()
    
              
class CreateMainWindow(QMainWindow):
    def __init__(self, *args, **kwargs):
        super(CreateMainWindow, self).__init__(*args, **kwargs)
        
        self.mayaMainWindow = getMayaWindow()
        
        self.mayaMainWindow.setAcceptDrops(True)  
        self.mayaMainWindow.installEventFilter(filter)
 
        self.initUI()
               
        
    def initUI(self):
        mainHBox = QHBoxLayout(self)    

        label1 = MyLabel(self)
        
        mainHBox.addWidget(label1)        
        # Parent under main Maya window
        self.setParent(self.mayaMainWindow)
        self.setWindowFlags(Qt.Window)
        
        #self.setObjectName('CreateMainWindow_611')
        self.setWindowTitle('Drag This')
        self.setGeometry(100, 100, 550, 350)
        
        

    def closeEvent(self, e):
        '''
        Make sure the eventFilter is removed
        '''
        print 'closeEvent'
        self.mayaMainWindow.removeEventFilter(filter)
        return super(CreateMainWindow, self).closeEvent(e)

                    
class MyLabel(QLabel):
    def __init__(self, parent):
        super(MyLabel, self).__init__(parent)

        self.setStyleSheet("""
            background-color: black;
            color: white;
            font: bold;
            padding: 6px;
            border-width: 2px;
            border-style: solid;
            border-radius: 16px;
            border-color: white;
        """)
        
    def mouseMoveEvent(self, e):
        print 'e.buttons() = {}'.format(e.buttons())
        if e.buttons() != Qt.LeftButton:
            print 'Left button not detected.'
            return
        else:
            print 'Left button press detected.'

        # grab the button to a pixmap
        pixmap = QPixmap.grabWidget(self)


        # write the relative cursor position to mime data
        mimeData = QMimeData()
        # simple string with 'x,y'
        mimeData.setText('%d,%d' % (e.x(), e.y()))

        # make a QDrag
        drag = QDrag(self)
        # put our MimeData
        drag.setMimeData(mimeData)
        # set its Pixmap
        drag.setPixmap(pixmap)
        # shift the Pixmap so that it coincides with the cursor position
        drag.setHotSpot(e.pos())

        
        # below makes the pixmap half transparent
        painter = QPainter(pixmap)
        painter.setCompositionMode(painter.CompositionMode_DestinationIn)
        painter.fillRect(pixmap.rect(), QColor(0, 0, 0, 127))
        painter.end()

        mainWinDrag = QDrag(self)
        dropAction = drag.start(Qt.MoveAction)
        # start the drag operation
        # exec_ will return the accepted action from dropEvent
        #drag.exec_(Qt.DropAction.)
        if dropAction == Qt.MoveAction:
            print 'moved'
        else:
            print 'MoveAction = {}'.format(drag.exec_(Qt.MoveAction))
            print 'copied'

         
def main():
    ui = CreateMainWindow()
    ui.show()
    # ui.show(dockable=True, floating=True)

main()

To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_maya+unsub...@googlegroups.com.

Justin Israel

unread,
Nov 12, 2016, 4:59:52 PM11/12/16
to python_in...@googlegroups.com
Your code works under Maya 2015 / PySide (with the import statements adjusted for PySide and shiboken)

Not sure if this is specific to Maya 2017 + PySide2

- Justin


To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/python_inside_maya/360a57bf-1253-4bb8-9908-62ade6fef4af%40googlegroups.com.

Alec Fredericks

unread,
Nov 12, 2016, 5:59:35 PM11/12/16
to Python Programming for Autodesk Maya
Thanks for checking that, Justin. I could have sworn that I tried this in Maya 2016 and had the same problem but now that I try it there, it seems to work fine.
I've been barking up the wrong tree. Now I have to figure out if the drag-and-drop in 2017 is just implemented differently or broken.

Thanks again,
Alec
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_maya+unsub...@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_maya+unsub...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages