def setLine(self, line): """ Set the arrow base line (a `QLineF` in object coordinates). """ if self.__line != line: self.__line = line # local item coordinate system geom = self.geometry().translated(-self.pos()) if geom.isNull() and not line.isNull(): geom = QRectF(0, 0, 1, 1) arrow_shape = arrow_path_concave(line, self.lineWidth()) arrow_rect = arrow_shape.boundingRect() if not (geom.contains(arrow_rect)): geom = geom.united(arrow_rect) if self.__autoAdjustGeometry: # Shrink the geometry if required. geom = geom.intersected(arrow_rect) # topLeft can move changing the local coordinates. diff = geom.topLeft() line = QLineF(line.p1() - diff, line.p2() - diff) self.__arrowItem.setLine(line) self.__line = line # parent item coordinate system geom.translate(self.pos()) self.setGeometry(geom)
def zoom(self, logAmount): scale = math.exp(logAmount) border = self.getViewportRect() mid = border.center() border.translate(-mid) border = QRectF(border.topLeft() * scale, border.bottomRight() * scale) border.translate(mid) self.moveViewRect(border.intersected(self.sceneRect()))
def adjustGeometry(self): """ Adjust the widget geometry to exactly fit the arrow inside while preserving the arrow path scene geometry. """ # local system coordinate geom = self.geometry().translated(-self.pos()) line = self.__line arrow_rect = self.__arrowItem.shape().boundingRect() if geom.isNull() and not line.isNull(): geom = QRectF(0, 0, 1, 1) if not (geom.contains(arrow_rect)): geom = geom.united(arrow_rect) geom = geom.intersected(arrow_rect) diff = geom.topLeft() line = QLineF(line.p1() - diff, line.p2() - diff) geom.translate(self.pos()) self.setGeometry(geom) self.setLine(line)
def _selectedRect(self): if self._p1 is None or self._p2 is None: return QRectF(0, 0, 0, 0) rect = QRectF(QPoint(*self._p1), QPoint(*self._p2)) return rect.intersected(self._mask_rect)
class RegionSelector: '''Class to handle coordinating multiple selector windows for a multimonitor setup. ''' def __init__(self, x, y, w, h, pixmap): self.moving = self.drawing = self.resizing = False self.bounds = QRectF(x, y, w, h) self.selectors = [] self.selection = None for screen in QApplication.screens(): # make a new selector for this screen # TODO: Support limited subset of screens? geo = screen.geometry() sel = Selector(geo.x(), geo.y(), geo.width(), geo.height(), pixmap, self) self.selectors.append(sel) #endfor #enddef def exec_(self): cPos = QCursor.pos() QCursor.setPos( 0, 0 ) # XFCE workaround. In XCFE, window position is relative to the cursor position for sel in self.selectors: sel.show() QCursor.setPos(cPos) self.selectors[-1].exec_() #enddef def updateSelection(self): for s in self.selectors: s.updateSelection() #enddef def mousePressEvent(self, e): pos = e.globalPos() self.moving = self.drawing = self.resizing = False if self.selection is None or not self.selection.contains(pos): self.drawing = True self.selection = None self.selectionStart = pos #elif in corner #elif on line else: # in self.moving = True self.selBeforeMove = self.selection self.moveOrigin = pos #endif self.updateSelection() #enddef def mouseMoveEvent(self, e): pos = e.globalPos() if self.drawing: if pos.x() != self.selectionStart.x() and pos.y( ) != self.selectionStart.y(): self.selection = QRectF(QPointF(self.selectionStart), QPointF(pos)).normalized() self.selection = self.selection.intersected(self.bounds) self.updateSelection() #endif elif self.moving: delta = pos - self.moveOrigin moved = self.selBeforeMove.translated(delta) # TODO: this cause the bounds to be "sticky", since trying to move back after pushing it 50px off the edge # means we must re-traverse the other 49 "off screen" pixels before we get some visible movement minX, maxX = self.bounds.x( ), self.bounds.x() + self.bounds.width() - moved.width() minY, maxY = self.bounds.y( ), self.bounds.y() + self.bounds.height() - moved.height() moved.moveTo(min(max(minX, moved.x()), maxX), min(max(minY, moved.y()), maxY)) self.selection = moved.intersected(self.bounds) self.updateSelection() #endif #enddef def mouseReleaseEvent(self, e): self.moving = self.drawing = self.resizing = False self.updateSelection() #enddef def keyReleaseEvent(self, event): if event.key() == Qt.Key_Escape: self.selection = None self.close() elif event.key() in (Qt.Key_Enter, Qt.Key_Return): if self.selection: self.close() #endif #endif #enddef def close(self): for s in self.selectors: s.close()