So I’ve been working on this and trying to add a rect drag selection. Now I’m stuck at getting said selection to only select the parts where I have painted masks. Unfortunately it sees the QLabelButton, not filtering to its mask and because the QLabelButton is as big as the window, it will always be selected no matter where I drag and release.
I’ve posted on stack overflow too. If this is an illegal cross-post I’ll delete it. But I could use any help or ideas.
resources
from maya import OpenMayaUI
import pymel.core as pm
from PySide2 import QtCore, QtGui, QtWidgets
from PySide2.QtGui import QPixmap, QIcon
from shiboken2 import wrapInstance
import urllib
class QLabelButton(QtWidgets.QLabel):
def mouseReleaseEvent(self, ev):
self.emit(QtCore.SIGNAL('clicked()'))
def main_maya_window():
main_window_ptr = OpenMayaUI.MQtUtil.mainWindow()
return wrapInstance(long(main_window_ptr), QtWidgets.QWidget)
class rubberBandUI(QtWidgets.QDialog):
def __init__(self, parent=main_maya_window()):
super(rubberBandUI, self).__init__(parent)
imgRes = [512, 512]
self.setMinimumSize(imgRes[0], imgRes[1])
self.setMaximumSize(imgRes[0], imgRes[1])
# resources
bgPath = r"C://bg.png"
maskPath = r"C://bg_mask.png"
# background image
self.bg = QtWidgets.QLabel('bg', self)
self.bg.setPixmap(QtGui.QPixmap(bgPath))
# mask image
self.mask = QLabelButton('mask', self)
self.mask.setGeometry(0, 0, imgRes[0], imgRes[1])
self.mask.setAlignment(QtCore.Qt.AlignCenter)
self.mask.setMask(maskPath)
self.connect(self.mask, QtCore.SIGNAL('clicked()'), lambda: self.onClick(self.mask) )
self.mask.setStyleSheet("""QLabel:hover{background-color: rgba(64, 128, 255, 180); border: 1px solid blue;}""")
# create rubber band selection
self.rubberBand = QtWidgets.QRubberBand(QtWidgets.QRubberBand.Rectangle, self)
# Create variables that will be handling the moving logic.
self.sourceGeo = None
self.altPoint = None
self.delta = None
def mousePressEvent(self, event):
if event.button() == QtCore.Qt.LeftButton:
self.origin = event.pos()
self.drag_selection = QtCore.QRect(self.origin, QtCore.QSize())
self.rubberBand.setGeometry(self.drag_selection)
self.rubberBand.show()
# Must implement this event to detect when alt gets released
def keyReleaseEvent(self, event):
if event.key() == QtCore.Qt.Key_Alt:
if self.delta is not None:
# This is important: Add delta to origin so that it shifts it over.
# This is needed if the user repeatedly pressed alt to move it, otherwise it would pop.
self.origin += self.delta
# Reset the rest of the variables.
self.sourceGeo = None
self.altPoint = None
self.delta = None
def mouseMoveEvent(self, event):
if event.modifiers() == QtCore.Qt.AltModifier:
# Get the point where alt is pressed and the selection's current geometry.
if self.altPoint is None:
self.sourceGeo = self.rubberBand.geometry()
self.altPoint = event.pos()
self.delta = event.pos() - self.altPoint # Calculate difference from the point alt was pressed to where the cursor is now.
newGeo = QtCore.QRect(self.sourceGeo) # Create a copy
newGeo.moveTopLeft(self.sourceGeo.topLeft() + self.delta) # Apply the delta onto the geometry to move it.
self.rubberBand.setGeometry(newGeo) # Move the selection!
else:
self.drag_selection = QtCore.QRect(self.origin, event.pos()).normalized()
self.rubberBand.setGeometry(self.drag_selection)
def mouseReleaseEvent(self, event):
if self.rubberBand.isVisible():
self.rubberBand.hide()
selected = []
rect = self.rubberBand.geometry()
#self.cropImage(rect)
for child in self.findChildren(QLabelButton):
if rect.intersects(child.geometry()):
selected.append(child)
print 'Selection Contains:\n ',
if selected:
print ' '.join(
'Button: %s\n' % child.text() for child in selected)
else:
print ' Nothing\n'
# label click function to print its name
def onClick(self, button):
print '%s clicked' % button.text()
if __name__ == '__main__':
app = QtWidgets.QApplication.instance()
if app == None:
app = QtWidgets.QApplication([])
win = rubberBandUI()
#Set WA_DeleteOnClose attribute
win.setAttribute(QtCore.Qt.WA_DeleteOnClose)
win.show()
app.exec_()
sys.exit()