Instantly share code, notes, and snippets.
Last active
March 14, 2023 22:23
-
Star
1
(1)
You must be signed in to star a gist -
Fork
0
(0)
You must be signed in to fork a gist
-
Save oglops/3aeea9fa48a4a5dce4ca84ace62f60e6 to your computer and use it in GitHub Desktop.
drag from qtableview and drop on maya shelf to insert shelf button
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from __future__ import division | |
import maya.OpenMayaUI | |
import maya.cmds | |
from pymel.core import melGlobals | |
from PySide2 import QtCore, QtGui, QtWidgets | |
import shiboken2 | |
import six | |
if six.PY3: | |
long = int | |
def get_qobj(ui, widget=QtCore.QObject): | |
if isinstance(ui, six.string_types): | |
ptr = maya.OpenMayaUI.MQtUtil.findControl(ui) | |
if ptr is None: | |
ptr = maya.OpenMayaUI.MQtUtil.findLayout(ui) | |
if ptr is None: | |
ptr = maya.OpenMayaUI.MQtUtil.findMenuItem(ui) | |
if ptr is not None: | |
return shiboken2.wrapInstance(long(ptr), widget) | |
else: | |
return shiboken2.wrapInstance(long(ui), widget) | |
def get_maya_ui(qobj): | |
return maya.OpenMayaUI.MQtUtil.fullName(long(shiboken2.getCppPointer(qobj)[0])) | |
class TableModel(QtCore.QAbstractTableModel): | |
def __init__(self, data): | |
super(TableModel, self).__init__() | |
self._data = data | |
def data(self, index, role): | |
if role == QtCore.Qt.DisplayRole: | |
return self._data[index.row()][index.column()] | |
def rowCount(self, index): | |
return len(self._data) | |
def columnCount(self, index): | |
return len(self._data[0]) | |
def flags(self, index): | |
return ( | |
QtCore.Qt.ItemIsEnabled | |
| QtCore.Qt.ItemIsSelectable | |
| QtCore.Qt.ItemIsDragEnabled | |
) | |
class Table(QtWidgets.QTableView): | |
dropped = QtCore.Signal(QtCore.QPoint, list) | |
def __init__(self, parent=None): | |
super(Table, self).__init__(parent) | |
self.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows) | |
self.setDragDropMode(QtWidgets.QAbstractItemView.DragDrop) | |
self.setDropIndicatorShown(True) | |
def startDrag(self, supportedActions): | |
listsQModelIndex = self.selectedIndexes() | |
if listsQModelIndex: | |
dragQDrag = QtGui.QDrag(self) | |
defaultDropAction = QtCore.Qt.CopyAction | |
dataQMimeData = self.model().mimeData(listsQModelIndex) | |
dragQDrag.setMimeData(dataQMimeData) | |
# dragQDrag.targetChanged.connect(self.__test) | |
print("drag start") | |
dragQDrag.exec_(supportedActions, defaultDropAction) | |
pos = QtGui.QCursor.pos() | |
data = [x.data() for x in listsQModelIndex] | |
n = 2 | |
data = [data[i : i + n] for i in range(0, len(data), n)] | |
self.dropped.emit(pos, data) | |
class MainWindow(QtWidgets.QMainWindow): | |
def __init__(self, parent=None): | |
super(MainWindow, self).__init__(parent) | |
self.table = Table() | |
self.table.horizontalHeader().setStretchLastSection(True) | |
data = [ | |
["awesome", "1.0"], | |
["ordinary", "0.3"], | |
["good", "1.2"], | |
["bad", "0.1"], | |
] | |
self.model = TableModel(data) | |
self.table.setModel(self.model) | |
self.setCentralWidget(self.table) | |
self.table.dropped.connect(self.insertButton) | |
def insertButton(self, pos, data): | |
print('insert at %s' % pos, data) | |
shelfTabLayout = melGlobals["gShelfTopLevel"] | |
shelfTabLayoutO = get_qobj(shelfTabLayout, QtWidgets.QWidget) | |
pos_local = shelfTabLayoutO.mapFromGlobal(pos) | |
maya.cmds.shelfTabLayout(shelfTabLayout, query=True, selectTabIndex=True) | |
widget = QtWidgets.QApplication.widgetAt(pos) | |
ui = get_maya_ui(widget) | |
ui = ui.rstrip("|") | |
print('dropped on', ui) | |
current = maya.cmds.shelfTabLayout(shelfTabLayout, q=1, st=1) | |
if ui.endswith("%s|mayaLayoutInternalWidget" % current): | |
move = False | |
else: | |
ui_type = maya.cmds.objectTypeUI(ui) | |
if ui_type in ("shelfButton", "separator"): | |
move = True | |
elif ui_type == "tabLayout": | |
move = False | |
# figure out which tab it is | |
tabWidget = widget.parent() | |
bar = tabWidget.tabBar() | |
shelves = len( | |
maya.cmds.shelfTabLayout(shelfTabLayout, query=True, ca=True) | |
) | |
tab_width = bar.width() / shelves | |
# estimated tab | |
index = int((pos_local.x() // tab_width)) + 1 | |
print( | |
"dropped on", | |
index, | |
maya.cmds.shelfTabLayout(shelfTabLayout, q=1, tabLabelIndex=1)[ | |
index | |
], | |
) | |
# now you can append shelf button to that shelf tab and | |
# activate it | |
return | |
else: | |
return | |
# append shelf button to currente tab | |
buttons = [] | |
for label, ver in data: | |
button = maya.cmds.shelfButton( | |
label=label, | |
annotation="I am %s" % label, | |
p="%s|%s" % (shelfTabLayout, current), | |
command="print(%r)" % label, | |
image1=":/ambientlight.png", | |
imageOverlayLabel=label, | |
) | |
buttons.append(button) | |
if move: | |
# determine drop on left or right button under cursor drop pos | |
width = maya.cmds.control(ui, q=1, w=1) | |
# left = pos_local.x() // width | |
existing = maya.cmds.shelfLayout(current, q=1, ca=1) | |
index = existing.index(ui.split("|")[-1]) | |
left = sum([maya.cmds.control(x, q=1, w=1) for x in existing[:index] if maya.cmds.control(x, q=1, vis=1)]) | |
right = 1 if (pos_local.x() - left) > width / 2.0 else 0 | |
index = index + 1 + right | |
for b in reversed(buttons): | |
maya.cmds.shelfLayout(current, e=1, position=[b, index]) | |
window = MainWindow() | |
window.show() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment