Skip to content

Instantly share code, notes, and snippets.

@Boon-in-Oz
Last active April 26, 2019 01:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Boon-in-Oz/5134664a13cffb6f67075edfe2ff6f8a to your computer and use it in GitHub Desktop.
Save Boon-in-Oz/5134664a13cffb6f67075edfe2ff6f8a to your computer and use it in GitHub Desktop.
from PySide2 import QtCore, QtWidgets
from shiboken2 import wrapInstance
try:
import maya.OpenMayaUI as omui
except:
# We're not in Maya. No big deal.
pass
class FlowLayout(QtWidgets.QLayout):
def __init__(self, parent=None, margin=0, spacing=-1):
super(FlowLayout, self).__init__(parent)
if parent is not None:
self.setContentsMargins(margin, margin, margin, margin)
self.setSpacing(spacing)
self.itemList = []
def __del__(self):
item = self.takeAt(0)
while item:
item = self.takeAt(0)
def addItem(self, item):
self.itemList.append(item)
def count(self):
return len(self.itemList)
def itemAt(self, index):
if index >= 0 and index < len(self.itemList):
return self.itemList[index]
return None
def takeAt(self, index):
if index >= 0 and index < len(self.itemList):
return self.itemList.pop(index)
return None
def expandingDirections(self):
return QtCore.Qt.Orientations(QtCore.Qt.Orientation(0))
def hasHeightForWidth(self):
return True
def heightForWidth(self, width):
oldWidth = self.geometry().width() - 2 * self.contentsMargins().top()
_, oldHeight = self.doLayout(QtCore.QRect(0, 0, oldWidth, 0), True)
_, height = self.doLayout(QtCore.QRect(0, 0, width, 0), True)
print 'heightForWidth', width, oldWidth, height, oldHeight
if height != oldHeight:
self.update()
return height
def setGeometry(self, rect):
super(FlowLayout, self).setGeometry(rect)
self.doLayout(rect, False)
def sizeHint(self):
return self.minimumSize()
def minimumSize(self):
width = self.geometry().width() - 2 * self.contentsMargins().top()
minWidth, minHeight = self.doLayout(QtCore.QRect(0, 0, width, 0), True)
print 'minimumSize', width, minWidth, minHeight
size = QtCore.QSize(minWidth, minHeight)
margin, _, _, _ = self.getContentsMargins()
size += QtCore.QSize(2 * margin, 2 * margin)
return size
def doLayout(self, rect, testOnly):
x = rect.x()
y = rect.y()
lineHeight = 0
maxLineWidth = 0
for item in self.itemList:
wid = item.widget()
spaceX = self.spacing() + wid.style().layoutSpacing(
QtWidgets.QSizePolicy.PushButton,
QtWidgets.QSizePolicy.PushButton,
QtCore.Qt.Horizontal
)
spaceY = self.spacing() + wid.style().layoutSpacing(
QtWidgets.QSizePolicy.PushButton,
QtWidgets.QSizePolicy.PushButton,
QtCore.Qt.Vertical
)
nextX = x + item.sizeHint().width() + spaceX
if nextX - spaceX > rect.right() and lineHeight > 0:
maxLineWidth = max(x-rect.x(),
maxLineWidth,
item.sizeHint().width())
x = rect.x()
y = y + lineHeight + spaceY
nextX = x + item.sizeHint().width() + spaceX
lineHeight = 0
if not testOnly:
item.setGeometry(
QtCore.QRect(QtCore.QPoint(x, y), item.sizeHint())
)
x = nextX
lineHeight = max(lineHeight, item.sizeHint().height())
return maxLineWidth, y + lineHeight - rect.y()
def findHostMayaWin():
''' Returns the Maya main window. '''
ptr = omui.MQtUtil.mainWindow()
hostwin = wrapInstance(long(ptr), QtWidgets.QWidget)
return hostwin
def closePreviousTestWindow(qtObjectName):
''' Closes any existing window with qtObjectName under Maya. '''
ptr = omui.MQtUtil.findControl(qtObjectName)
if ptr is not None:
oldwin = wrapInstance(long(ptr), QtWidgets.QWidget)
oldwin.setAttribute(QtCore.Qt.WA_DeleteOnClose, True)
oldwin.close()
class TestWindow(QtWidgets.QMainWindow):
''' Minimal working example of the FlowLayout. '''
qtObjectName = "FlowLayout_Test_Window"
def __init__(self, parent):
super(TestWindow, self).__init__(parent)
self.setObjectName(self.qtObjectName)
self.setWindowTitle('FlowLayout Test')
self.setCentralWidget(QtWidgets.QWidget(self))
flowLayout = FlowLayout()
for text in ("Lorem ipsum dolor sit amet, consectetur adipiscing "
"elit. Ut eu metus ultricies, laoreet erat ut, pharetra "
"nunc. Suspendisse ultrices sem et sapien congue mattis."
).split():
flowLayout.addWidget(QtWidgets.QPushButton(text))
self.centralWidget().setLayout(flowLayout)
def run_maya():
""" Shows the TestWindoww as a child of the main Maya window. """
hostWin = findHostMayaWin()
closePreviousTestWindow(TestWindow.qtObjectName)
testWin = TestWindow(hostWin)
testWin.show()
return testWin
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
mainWin = TestWindow()
mainWin.show()
sys.exit(app.exec_())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment