lang/pysideex/ DraggableRectangles001


import sys
from PySide6.QtCore import *
from PySide6.QtGui import *
from PySide6.QtWidgets import *
from PySide6.QtNetwork import *

app = QApplication(sys.argv)

win = QMainWindow()
win.setFixedSize(640,512)

class Rect:
  def __init__(self,x,y,w,h,color):
    self.x = x
    self.y = y
    self.w = w
    self.h = h
    self.color = color
    self.sel = False
  def paint(self,painter,stroke=False):
    rect = QRect(self.x,self.y,self.w,self.h)
    painter.fillRect(rect,self.color)
    if stroke:
      painter.save()
      painter.pen().setWidth(2)
      painter.pen().setColor(QColor.fromRgb(0,0,0))
      painter.setBrush(Qt.NoBrush)
      painter.drawRect(rect)
      painter.restore()
  def hit(self,x,y):
    if x < self.x:
      return False
    if y < self.y:
      return False
    if x > self.x + self.w:
      return False
    if y > self.y + self.h:
      return False
    return True



class Rects(QWidget):
  def __init__(self,*xs,**kw):
    super().__init__(*xs,**kw)
    self.rects = [
      Rect(10,10,100,200,QColor.fromRgb(255,0,0)),
      Rect(30,30,100,200,QColor.fromRgb(0,255,0))
    ]
    self.selrect = None
    self.rx0 = 0
    self.ry0 = 0
    self.x0 = 0
    self.y0 = 0
  def paintEvent(self,event):
    with QPainter(self) as painter:
      for r in self.rects:
        r.paint(painter,r.sel)
  def mousePressEvent(self,event):
    pos = event.position().toPoint()
    x,y = pos.x(),pos.y()
    for r in reversed(self.rects):
      if r.hit(x,y):
        r.sel = True
        self.selrect = r
        self.rx0 = r.x
        self.ry0 = r.y
        self.x0 = x
        self.y0 = y
        self.update()
        break
    return super().mousePressEvent(event)
  def mouseReleaseEvent(self,event):
    if self.selrect:
      pos = event.position().toPoint()
      x,y = pos.x(),pos.y()
      dx,dy = x-self.x0,y-self.y0
      self.selrect.x = self.rx0+dx
      self.selrect.y = self.ry0+dy
      self.selrect.sel = False
      self.selrect = None
      self.update()
    return super().mouseReleaseEvent(event)
  def mouseMoveEvent(self,event):
    if self.selrect:
      pos = event.position().toPoint()
      x,y = pos.x(),pos.y()
      dx,dy = x-self.x0,y-self.y0
      self.selrect.x = self.rx0+dx
      self.selrect.y = self.ry0+dy
      self.update()
    return super().mouseMoveEvent(event)
rects = Rects()
win.setCentralWidget(rects)

win.show()


exit(app.exec())