Space Switch Tool 1.0 for Maya

I think creating a space switch setup in Maya can be fairly easy if you know how to code. However, editing and debugging the setup can be complicated and needs a management system to handle the data.

I made this tool so it is both animator and riggers friendly. The UI is pretty interactive and the requirements for creating the setup are minimal. When adding a new space the tool guides the user by loading the previous made setup info to the tool.
The Marking menu provides a fast way to switch between spaces and executes a script to maintain the objects transformation when switching between spaces.
In the Edit and Debug tab you can view all the driver spaces and also edit their order and display names. You can even remove any of them or the whole setup cleanly if you want with out worrying about leaving some connected nodes behind in the scene.

For full explanation please check the tool's documentation page. Here is a quick video that covers most of the tool's functionality.

Adding an Animated Gif to a QLabel with Pyside

Time for another tutorial  not for the drag and drop (Got a bit distracted with the inspiration for this tutorial) but for adding an animated gif to a QLabel.

In this example I am loading the file into a QByteArray so we don't keep that GIF in memory. However you can add the GIF file directly to the QMovie as the first argument.

If you can't display the GIF in your own code, double check the qt.conf file and make sure that it is referring to the correct plugins folder. 

PS: If you don't recognise the GIF shown in the tool, you can find the Video here.("You are welcome"). 

import sys
import os
from PySide import QtCore, QtGui
ImagesFolder=os.path.join(os.path.dirname(__file__),'images')

class CucumberGifWidget(QtGui.QLabel):
    def __init__(self, parent=None):
        super(CucumberGifWidget, self).__init__(parent)
        self.setAcceptDrops(True)
        self.setFrameStyle(QtGui.QFrame.WinPanel | QtGui.QFrame.Sunken)
        self.setAlignment(QtCore.Qt.AlignCenter)
        self.setSizePolicy(QtGui.QSizePolicy.MinimumExpanding, QtGui.QSizePolicy.MinimumExpanding)
        
        trashGif= open(os.path.join(ImagesFolder,'cucumber.gif'), 'rb').read()
        self.gifByteArray=QtCore.QByteArray(trashGif)
        self.gifBuffer=QtCore.QBuffer(self.gifByteArray)
        self.movie = QtGui.QMovie()
        self.movie.setFormat('GIF')
        self.movie.setDevice(self.gifBuffer)
        self.movie.setCacheMode(QtGui.QMovie.CacheAll)
        self.movie.setSpeed(100)
        self.setMovie(self.movie)
        self.movie.jumpToFrame(0)

    def dragEnterEvent(self, event):
        if event.mimeData().hasImage():
            event.setDropAction(QtCore.Qt.MoveAction)
            event.accept()
        else:
            event.ignore()

    def dropEvent(self, event):
        event.setDropAction(QtCore.Qt.MoveAction)
        if event.mimeData().hasImage():
            if "cucumber" in event.mimeData().text():
                self.movie.start()
                event.source().setParent(None)
                event.source().deleteLater()
            else:
                event.accept()
        else:
            event.ignore()

Drag and drop with Qt and PySide

I have always been using (well at least the past 7 years) QT for creating interfaces for my PySide/PyQt applications. Lately I've decided to dive a bit deeper to create and experiment with more complex behaviours. 

Starting with a convenient behaviour : Drag and Drop.

In the example I am sharing here I re-implemented the drag and drop related methods of a QLabel and a QWidget so we are able to drag the label into the widget. What actually happens is that when we drop the label on  the widget we create another Label with the same information,  it is a Copying action.

TODO: In the upcoming weeks we will add the functionality of re-arranging the labels in the Drop widget and also from one Drop widget to another.
import sys
from PySide import QtCore, QtGui

class InitialCard(QtGui.QLabel):
    def __init__(self, text, parent):
        super(InitialCard, self).__init__(text, parent)
        self.setAutoFillBackground(True)
        self.setFrameStyle(QtGui.QFrame.WinPanel|QtGui.QFrame.Sunken)
        newFont = QtGui.QFont("MsReferenceSansSerif", 10)
        newFont.setBold(False)
        self.setFont(newFont)
        self.setMinimumSize(90, 25)
        self.setMaximumHeight(30)
        self.setAlignment(QtCore.Qt.AlignCenter)
        self.mimeText=self.text()

    def mouseMoveEvent(self, event):
        if not self.text():
            return
        mimeData = QtCore.QMimeData()
        mimeData.setText(self.mimeText)
        drag = QtGui.QDrag(self)
        drag.setMimeData(mimeData)
        drag.exec_(QtCore.Qt.CopyAction | QtCore.Qt.MoveAction, QtCore.Qt.CopyAction)

class CardsDropWidget(QtGui.QWidget):

    def __init__(self, parent):
        super(CardsDropWidget, self).__init__(parent)
        self.setAcceptDrops(True)
        self.contentsVLO = QtGui.QVBoxLayout()
        self.contentsVLO.setAlignment(QtCore.Qt.AlignTop)
        self.setLayout(self.contentsVLO)
    
    def dragEnterEvent(self, event):
        if event.mimeData().hasText():
            event.setDropAction(QtCore.Qt.CopyAction)
            event.accept()
        else:
            event.ignore()

    def dropEvent(self, event):
        if event.mimeData().hasText():
            cardSource=event.source()
            cardText=cardSource.text()
            if not cardSource in self.children():
                newCard = InitialCard(cardText, self)
                self.contentsVLO.addWidget(newCard)
                cardSource.clear()
            else:
                event.ignore()
        else:
            event.ignore()

class MainDialogue(QtGui.QDialog):
    def __init__(self, parent=None):
        super(MainDialogue, self).__init__(parent)
        self.label=InitialCard("initial", self)
        self.lineEdit=QtGui.QLineEdit("Create a Card Here!!")
        self.lineEdit.selectAll()
        self.scrollArea = QtGui.QScrollArea()
        self.scrollArea.setWidgetResizable(True)
        self.scrollContent = CardsDropWidget(self.scrollArea)
        self.scrollArea.setMinimumWidth(150)
        self.scrollArea.setWidget(self.scrollContent)
        self.dialogueLayout=QtGui.QHBoxLayout()
        self.labelLayout=QtGui.QVBoxLayout()
        self.labelLayout.addWidget(self.label)
        self.labelLayout.addWidget(self.lineEdit)
        self.labelLayout.addStretch()
        self.dialogueLayout.addWidget(self.scrollArea)
        self.dialogueLayout.addLayout(self.labelLayout)
        self.setLayout(self.dialogueLayout)
        self.setWindowTitle("Drag and Drop")
        self.setMinimumSize(300, 150)
        self.lineEdit.returnPressed.connect(self.createCardTxt_fn)
        
    def createCardTxt_fn(self):
        cardTxt=unicode(self.lineEdit.text())
        self.label.setText(cardTxt)

if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    window = MainDialogue()
    window.show()
    sys.exit(app.exec_())