def mousePressEvent(self, event): # 鼠标点击事件 if event.button() == Qt.LeftButton: flag = contexts['WindowManageWorker'].windowMode if flag == "Full": x = self.quickItems['mainTitleBar'].x() y = self.quickItems['mainTitleBar'].y() width = self.quickItems['mainTitleBar'].width() height = self.quickItems['mainTitleBar'].height() rect = QRect(x, y, width, height) if rect.contains(event.pos()): self.dragPosition = event.globalPos() - \ self.frameGeometry().topLeft() event.accept() elif flag == "Simple": x = self.rootObject().x() y = self.rootObject().y() width = self.rootObject().width() height = 40 rect = QRect(x, y, width, height) if rect.contains(event.pos()): self.dragPosition = event.globalPos() - \ self.frameGeometry().topLeft() event.accept() super(MainWindow, self).mousePressEvent(event) elif event.button() == Qt.RightButton: flag = contexts['WindowManageWorker'].windowMode if flag == "Full": if self.quickItems['webEngineViewPage'].isVisible(): event.ignore() else: event.accept() super(MainWindow, self).mousePressEvent(event)
def subcontrolOnPosition(self, position) : element = QStyle.SubControl() rect = QRect() rect = self._style.subControlRect(QStyle.CC_Slider, self._options.getUpperHandleOptions(), QStyle.SC_SliderHandle); if rect.contains(position) : return SubControl.UpperHandle; rect = self._style.subControlRect(QStyle.CC_Slider, self._options.getLowerHandleOptions(), QStyle.SC_SliderHandle); if rect.contains(position) : return SubControl.LowerHandle; rect = self._style.subControlRect(QStyle.CC_Slider, self._options.getGrooveOptions(), QStyle.SC_SliderGroove); if rect.contains(position) : return SubControl.Groove; return SubControl.No;
def _setCursor(self, mousePos): width = self.width() height = self.height() shadowMargin = self.shadowMargin resizeMargin = self.resizeMargin outsideRect = QRect(shadowMargin, shadowMargin, width - 2 * shadowMargin, height - 2 * shadowMargin) insideMargin = shadowMargin + resizeMargin insideRect = QRect(insideMargin, insideMargin, width - 2 * insideMargin, height - 2 * insideMargin) if outsideRect.contains(mousePos) and not insideRect.contains(mousePos) : leftRect = QRect(shadowMargin, insideMargin, resizeMargin, height - 2 * insideMargin) rightRect = QRect(width - insideMargin, insideMargin, resizeMargin, height - 2 * insideMargin) topRect = QRect(insideMargin, shadowMargin, width - 2 * insideMargin, resizeMargin) bottomRect = QRect(insideMargin, height - insideMargin, width - 2 * insideMargin, resizeMargin) leftTopRect = QRect(shadowMargin, shadowMargin, resizeMargin, resizeMargin) rightTopRect = QRect(width - insideMargin, shadowMargin, resizeMargin, resizeMargin) leftBottomRect = QRect(shadowMargin, height - insideMargin, resizeMargin, resizeMargin) rightBottomRect = QRect(width - insideMargin, height - insideMargin, resizeMargin, resizeMargin) if leftRect.contains(mousePos): self._resizeEdge = Qt.LeftEdge self.setCursor(QCursor(Qt.SizeHorCursor)) elif rightRect.contains(mousePos): self._resizeEdge = Qt.RightEdge self.setCursor(QCursor(Qt.SizeHorCursor)) elif topRect.contains(mousePos): self._resizeEdge = Qt.TopEdge self.setCursor(QCursor(Qt.SizeVerCursor)) elif bottomRect.contains(mousePos): self._resizeEdge = Qt.BottomEdge self.setCursor(QCursor(Qt.SizeVerCursor)) elif leftTopRect.contains(mousePos): self._resizeEdge = Qt.TopLeftCorner self.setCursor(QCursor(Qt.SizeFDiagCursor)) elif rightTopRect.contains(mousePos): self._resizeEdge = Qt.TopRightCorner self.setCursor(QCursor(Qt.SizeBDiagCursor)) elif leftBottomRect.contains(mousePos): self._resizeEdge = Qt.BottomLeftCorner self.setCursor(QCursor(Qt.SizeBDiagCursor)) elif rightBottomRect.contains(mousePos): self._resizeEdge = Qt.BottomRightCorner self.setCursor(QCursor(Qt.SizeFDiagCursor)) else: self._resizeEdge = None self.setCursor(QCursor(Qt.ArrowCursor)) else: self._resizeEdge = None self.setCursor(QCursor(Qt.ArrowCursor))
class IconButton(QObject): icon = QIcon() icon_border_ratio = float(0.1) clicked = pyqtSignal(QModelIndex) icon_border = 4 icon_size = 16 h = icon_size + 2 * icon_border w = h size = QSize(w, h) def __init__(self, parent=None): super(IconButton, self).__init__(parent=parent) # rect property contains the active zone for the button self.rect = QRect() self.icon_rect = QRect() self.icon_mode = QIcon.Normal def should_draw(self, _): return True def paint(self, painter, rect, _): # Update button activation rect from the drawing call self.rect = rect x = rect.left() + (rect.width() - self.w) / 2 y = rect.top() + (rect.height() - self.h) / 2 icon_rect = QRect(x, y, self.w, self.h) self.icon.paint(painter, icon_rect, mode=self.icon_mode) def check_clicked(self, event, _, __, index): if event.type() == QEvent.MouseButtonRelease and self.rect.contains( event.pos()): self.clicked.emit(index) return True return False def on_mouse_moved(self, pos, _): old_icon_mode = self.icon_mode if self.rect.contains(pos): self.icon_mode = QIcon.Selected else: self.icon_mode = QIcon.Normal return old_icon_mode != self.icon_mode def size_hint(self, _, __): return self.size
def __autoScrollAdvance(self): """Advance the auto scroll """ pos = QCursor.pos() pos = self.mapFromGlobal(pos) margin = self.__autoScrollMargin vvalue = self.verticalScrollBar().value() hvalue = self.horizontalScrollBar().value() vrect = QRect(0, 0, self.width(), self.height()) # What should be the speed advance = 10 # We only do auto scroll if the mouse is inside the view. if vrect.contains(pos): if pos.x() < vrect.left() + margin: self.horizontalScrollBar().setValue(hvalue - advance) if pos.y() < vrect.top() + margin: self.verticalScrollBar().setValue(vvalue - advance) if pos.x() > vrect.right() - margin: self.horizontalScrollBar().setValue(hvalue + advance) if pos.y() > vrect.bottom() - margin: self.verticalScrollBar().setValue(vvalue + advance) if self.verticalScrollBar().value() == vvalue and \ self.horizontalScrollBar().value() == hvalue: self.__stopAutoScroll() else: self.__stopAutoScroll() log.debug("Auto scroll advance")
def __accept(self, x, y, hit_type: CellState): log.debug( f" -- ACCEPTED -- hit on point ({x}, {y}) hit type: {hit_type}") cell = self.__field[y * 10 + x] if cell.data(0) != "intact": return if hit_type in [CellState.HIT, CellState.KILLED]: self.__setCell(x, y, 'hit') self.__runAnimation(x, y, "explosion", looped=True) for target in self.__targets: if (x, y) == target.data(0): self.__scene.removeItem(target) self.__targets.remove(target) break elif hit_type in [CellState.MISS]: self.__setCell(x, y, 'miss') self.__runAnimation(x, y, "splash", looped=False) if hit_type == CellState.KILLED: for ship in self.__placedShips: rotation = ship.data(0) length = ship.data(1).length position = ship.data(2) width = 1 if rotation.isVertical() else length height = length if rotation.isVertical() else 1 rect = QRect(position.x(), position.y(), width, height) if rect.contains(x, y): self.__scene.addItem(ship)
def mousePressEvent(self,event): x = self.showImgLabel.geometry().x() + self.MidLayout.geometry().x() y = self.showImgLabel.geometry().y() + self.MidLayout.geometry().y() w,h = self.showImgLabel.geometry().width(),self.showImgLabel.geometry().height() qrect = QRect(QPoint(x,y),QSize(w,h)) if qrect.contains(event.pos()) and Qt.RightButton == event.buttons(): self.bMousePress = True self.bDrawRect = False self.pressPos = event.pos() elif qrect.contains(event.pos()) and Qt.LeftButton == event.button(): self.bDrawRect = True self.bMousePress = False self.pressPos = event.pos() else: self.bMousePress = False self.bDrawRect = False
class IconButton(QObject): icon = QIcon() icon_border_ratio = float(0.1) clicked = pyqtSignal(QModelIndex) icon_border = 4 icon_size = 16 h = icon_size + 2 * icon_border w = h size = QSize(w, h) def __init__(self, parent=None): super(IconButton, self).__init__(parent=parent) # rect property contains the active zone for the button self.rect = QRect() self.icon_rect = QRect() self.icon_mode = QIcon.Normal def should_draw(self, _): return True def paint(self, painter, rect, _): # Update button activation rect from the drawing call self.rect = rect x = rect.left() + (rect.width() - self.w) / 2 y = rect.top() + (rect.height() - self.h) / 2 icon_rect = QRect(x, y, self.w, self.h) self.icon.paint(painter, icon_rect, mode=self.icon_mode) def check_clicked(self, event, _, __, index): if event.type() == QEvent.MouseButtonRelease and self.rect.contains(event.pos()): self.clicked.emit(index) return True return False def on_mouse_moved(self, pos, _): old_icon_mode = self.icon_mode if self.rect.contains(pos): self.icon_mode = QIcon.Selected else: self.icon_mode = QIcon.Normal return old_icon_mode != self.icon_mode def size_hint(self, _, __): return self.size
def _updateStatusArea(self, rect: QRect, dy: int): if dy: self._statusArea.scroll(0, dy) else: self._statusArea.update(0, rect.y(), self._statusArea.width(), rect.height()) if rect.contains(self.viewport().rect()): self._updateStatusAreaWidth()
def findPointAt(self, x, y): for i in range(len(self.points)): p = self.points[i] radius = 10 r = QRect(p[0] - radius, p[1] - radius, 2 * radius, 2 * radius) if r.contains(x, y): return i return -1
def actionAt(self, at): actionY = 0 for action in self.actionList: actionRect = QRect(0, actionY, self.actionWidth, self.actionHeight) if actionRect.contains(at): return action actionY += actionRect.height() return None
def _getTabIndexAt(self, pos: QPoint) -> (int, QRect): ts = self._tabSize tw, th = ts.width(), ts.height() for index in range(len(self._tabs)): rect = QRect(0, index * th, tw, th) if rect.contains(pos): return (index, rect) return (-1, QRect())
def update_gutter(self, rect: QRect, vertical_scroll_pixels: int): if vertical_scroll_pixels: self.gutter.scroll(0, vertical_scroll_pixels) self.gutter.update(0, rect.y(), self.gutter.width(), rect.height()) if rect.contains(self.viewport().rect()): self.update_gutter_area_width(0)
def __updateLineNumberArea(self, rect: QtCore.QRect, dy: int) -> None: if dy: self.__line_number_area.scroll(0, dy) else: width = self.__line_number_area.width() self.__line_number_area.update(0, rect.y(), width, rect.height()) if rect.contains(self.viewport().rect()): self.__updateLineNumberAreaWidth(0)
def update_line_number_area(self, rect: QRect, dy: int): if dy: self.line_number_area.scroll(0, dy) else: self.line_number_area.update(0, rect.y(), self.line_number_area.width(), rect.height()) if rect.contains(self.viewport().rect()): self.update_line_number_area_width(0)
def updateLineNumberArea(self, rect: QtCore.QRect, dy: int): if dy: self.lineNumberArea.scroll(0, dy) else: self.lineNumberArea.update(0, rect.y(), self.lineNumberArea.width(), rect.height()) if rect.contains(self.viewport().rect()): self.updateLineNumberAreaWidth()
def subcontrolOnPosition(self, position): element = QStyle.SubControl() rect = QRect() rect = self._style.subControlRect( QStyle.CC_Slider, self._options.getUpperHandleOptions(), QStyle.SC_SliderHandle) if rect.contains(position): return SubControl.UpperHandle rect = self._style.subControlRect( QStyle.CC_Slider, self._options.getLowerHandleOptions(), QStyle.SC_SliderHandle) if rect.contains(position): return SubControl.LowerHandle rect = self._style.subControlRect(QStyle.CC_Slider, self._options.getGrooveOptions(), QStyle.SC_SliderGroove) if rect.contains(position): return SubControl.Groove return SubControl.No
def paint(self, painter: QPainter, rect: QRect) -> None: painter.save() cur_x = rect.x() for feat in self.features: icon_rect = QRect(cur_x, rect.y(), self.ICON_SIZE.width(), self.ICON_SIZE.height()) feat.rect = icon_rect if rect.contains(icon_rect): # stay inside parent painter.drawPixmap(icon_rect, feat.icon().pixmap(self.ICON_SIZE)) cur_x += self.ICON_SIZE.width() + 1 painter.restore()
def is_on_workspace(widget: QWidget) -> bool: """checks if the widget is currently on the workspace Args: widget(QWidget): the widget to test_output if its on workspaceview """ widget_rect = QRect(widget.parent().mapToGlobal(widget.pos()), widget.size()) boundary_rect = QRect( WorkspaceView.main.mapToGlobal(WorkspaceView.boundary.pos()), WorkspaceView.boundary.size()) return boundary_rect.contains(widget_rect)
def mousePressEvent(self, event): if event.button() != Qt.LeftButton: return size = self.height() / 2.0 rect = QRect(self.width() - size, size * 0.5, size, size) if rect.contains(event.pos()): self.clear() self.valid = True event.accept()
class Example(QWidget): def __init__(self): super().__init__() self.initUI() def initUI(self): self.rect = QRect(20, 20, 80, 80) self.alpha = 1 self.m = MyThread() self.m.fading.connect(self.fade) self.setGeometry(300, 300, 250, 150) self.setWindowTitle('Hit test') self.show() def paintEvent(self, event): painter = QPainter() painter.begin(self) self.drawRectangle(painter) painter.end() def fade(self, alpha): self.alpha = alpha self.repaint() def mousePressEvent(self, e): if e.button() == Qt.LeftButton \ and self.alpha==1: x = e.x() y = e.y() if self.rect.contains(x, y): if not self.m.isRunning(): self.m.start() def drawRectangle(self, painter): painter.setOpacity(self.alpha) painter.setBrush(QBrush(Qt.black)) painter.setPen(Qt.NoPen) painter.drawRect(self.rect) def closeEvent(self, e): if self.m.isRunning(): self.m.quit()
def is_visible(elem, mainframe): """Check if the given element is visible in the frame. We need this as a standalone function (as opposed to a WebElementWrapper method) because we want to check this before wrapping when hinting for performance reasons. Args: elem: The QWebElement to check. mainframe: The QWebFrame in which the element should be visible. """ if elem.isNull(): raise IsNullError("Got called on a null element!") # CSS attributes which hide an element hidden_attributes = { 'visibility': 'hidden', 'display': 'none', } for k, v in hidden_attributes.items(): if elem.styleProperty(k, QWebElement.ComputedStyle) == v: return False elem_geometry = elem.geometry() if not elem_geometry.isValid() and elem_geometry.x() == 0: # Most likely an invisible link return False # First check if the element is visible on screen elem_rect = rect_on_view(elem, elem_geometry=elem_geometry) mainframe_geometry = mainframe.geometry() if elem_rect.isValid(): visible_on_screen = mainframe_geometry.intersects(elem_rect) else: # We got an invalid rectangle (width/height 0/0 probably), but this # can still be a valid link. visible_on_screen = mainframe_geometry.contains( elem_rect.topLeft()) # Then check if it's visible in its frame if it's not in the main # frame. elem_frame = elem.webFrame() framegeom = QRect(elem_frame.geometry()) if not framegeom.isValid(): visible_in_frame = False elif elem_frame.parentFrame() is not None: framegeom.moveTo(0, 0) framegeom.translate(elem_frame.scrollPosition()) if elem_geometry.isValid(): visible_in_frame = framegeom.intersects(elem_geometry) else: # We got an invalid rectangle (width/height 0/0 probably), but # this can still be a valid link. visible_in_frame = framegeom.contains(elem_geometry.topLeft()) else: visible_in_frame = visible_on_screen return all([visible_on_screen, visible_in_frame])
def mapSelections(self): self.selections = [] rect = QRect(self.canvas.rubberBand.geometry()) for pix in self.scene.items(): if pix.type == 'pix': p = pix.sceneBoundingRect() x = int(p.x() + p.width() / 2) y = int(p.y() + p.height() / 2) if rect.contains(x, y): pix.setSelected(True) self.selections.append(pix.id) elif pix.zValue() <= common["pathZ"]: break
def _is_visible(self, mainframe): """Check if the given element is visible in the given frame. This is not public API because it can't be implemented easily here with QtWebEngine, and is only used via find_css(..., only_visible=True) via the tab API. """ self._check_vanished() # CSS attributes which hide an element hidden_attributes = { 'visibility': 'hidden', 'display': 'none', 'opacity': '0', } for k, v in hidden_attributes.items(): if (self._elem.styleProperty(k, QWebElement.ComputedStyle) == v and 'ace_text-input' not in self.classes()): return False elem_geometry = self._elem.geometry() if not elem_geometry.isValid() and elem_geometry.x() == 0: # Most likely an invisible link return False # First check if the element is visible on screen elem_rect = self.rect_on_view(elem_geometry=elem_geometry) mainframe_geometry = mainframe.geometry() if elem_rect.isValid(): visible_on_screen = mainframe_geometry.intersects(elem_rect) else: # We got an invalid rectangle (width/height 0/0 probably), but this # can still be a valid link. visible_on_screen = mainframe_geometry.contains( elem_rect.topLeft()) # Then check if it's visible in its frame if it's not in the main # frame. elem_frame = self._elem.webFrame() framegeom = QRect(elem_frame.geometry()) if not framegeom.isValid(): visible_in_frame = False elif elem_frame.parentFrame() is not None: framegeom.moveTo(0, 0) framegeom.translate(elem_frame.scrollPosition()) if elem_geometry.isValid(): visible_in_frame = framegeom.intersects(elem_geometry) else: # We got an invalid rectangle (width/height 0/0 probably), but # this can still be a valid link. visible_in_frame = framegeom.contains(elem_geometry.topLeft()) else: visible_in_frame = visible_on_screen return all([visible_on_screen, visible_in_frame])
def _is_visible(self, mainframe: QWebFrame) -> bool: """Check if the given element is visible in the given frame. This is not public API because it can't be implemented easily here with QtWebEngine, and is only used via find_css(..., only_visible=True) via the tab API. """ self._check_vanished() # CSS attributes which hide an element hidden_attributes = { 'visibility': 'hidden', 'display': 'none', 'opacity': '0', } for k, v in hidden_attributes.items(): if (self._elem.styleProperty(k, QWebElement.ComputedStyle) == v and 'ace_text-input' not in self.classes()): return False elem_geometry = self._elem.geometry() if not elem_geometry.isValid() and elem_geometry.x() == 0: # Most likely an invisible link return False # First check if the element is visible on screen elem_rect = self.rect_on_view(elem_geometry=elem_geometry) mainframe_geometry = mainframe.geometry() if elem_rect.isValid(): visible_on_screen = mainframe_geometry.intersects(elem_rect) else: # We got an invalid rectangle (width/height 0/0 probably), but this # can still be a valid link. visible_on_screen = mainframe_geometry.contains( elem_rect.topLeft()) # Then check if it's visible in its frame if it's not in the main # frame. elem_frame = self._elem.webFrame() framegeom = QRect(elem_frame.geometry()) if not framegeom.isValid(): visible_in_frame = False elif elem_frame.parentFrame() is not None: framegeom.moveTo(0, 0) framegeom.translate(elem_frame.scrollPosition()) if elem_geometry.isValid(): visible_in_frame = framegeom.intersects(elem_geometry) else: # We got an invalid rectangle (width/height 0/0 probably), but # this can still be a valid link. visible_in_frame = framegeom.contains(elem_geometry.topLeft()) else: visible_in_frame = visible_on_screen return all([visible_on_screen, visible_in_frame])
def inArea(self, point): w = self.size().width() h = self.size().height() o1 = QPoint(w / 2 - self.mwidth / 2, h / 2) o2 = QPoint(w / 2 + self.mwidth / 2, h / 2) mrect = QRect(w / 2 - self.mwidth / 2, h / 2 - self.radius, self.mwidth, self.radius * 2) if mrect.contains(point): return True if (point-o1).manhattanLength() <= self.radius or \ (point-o2).manhattanLength() <= self.radius: return True return False
def editorEvent(self, event, model, option, index): if event.type() in (QEvent.MouseButtonPress, QEvent.MouseButtonRelease): no_bottom_right = QPoint(self.number_rect_x, option.rect.bottom()) no_rect = QRect(option.rect.topLeft(), no_bottom_right) mouse_event = QMouseEvent(event) if no_rect.contains(mouse_event.pos()): if event.type() == QEvent.MouseButtonPress: self.play_btn_pressed = True if event.type() == QEvent.MouseButtonRelease: if self.play_btn_pressed is True: self.parent().play_song_needed.emit(index.data(Qt.UserRole)) if event.type() == QEvent.MouseButtonRelease: self.play_btn_pressed = False return super().editorEvent(event, model, option, index)
def mouseMoveEvent(self, event): if self._interaction.moving: mouse_position = event.globalPos() offset = mouse_position - self._interaction.mouse_last_position if self.parent() is not None: parent_rect = self.parent().rect() old_geometry = self.geometry() new_geometry = old_geometry.translated(offset) if new_geometry.left() < 0: new_geometry.moveLeft(0) if new_geometry.top() < 0: new_geometry.moveTop(0) if new_geometry.right() > parent_rect.right(): new_geometry.moveRight(parent_rect.right()) if new_geometry.bottom() > parent_rect.bottom(): new_geometry.moveBottom(parent_rect.bottom()) offset = new_geometry.topLeft() - old_geometry.topLeft() self.move(self.pos() + offset) self._interaction.mouse_last_position += offset elif self._interaction.resizing: mouse_position = event.globalPos() delta_y = mouse_position.y() - self._interaction.mouse_last_position.y() geometry = self.geometry() if self._interaction.resize_corner is self.TopLeftCorner: delta_x = -(self.width_for_height(geometry.height() - delta_y) - geometry.width()) geometry.setTopLeft(geometry.topLeft() + QPoint(delta_x, delta_y)) elif self._interaction.resize_corner is self.TopRightCorner: delta_x = +(self.width_for_height(geometry.height() - delta_y) - geometry.width()) geometry.setTopRight(geometry.topRight() + QPoint(delta_x, delta_y)) elif self._interaction.resize_corner is self.BottomLeftCorner: delta_x = -(self.width_for_height(geometry.height() + delta_y) - geometry.width()) geometry.setBottomLeft(geometry.bottomLeft() + QPoint(delta_x, delta_y)) else: delta_x = +(self.width_for_height(geometry.height() + delta_y) - geometry.width()) geometry.setBottomRight(geometry.bottomRight() + QPoint(delta_x, delta_y)) if self.minimumHeight() <= geometry.height() <= self.maximumHeight() and (self.parent() is None or self.parent().rect().contains(geometry)): self.setGeometry(geometry) self._interaction.mouse_last_position = mouse_position elif self.interactive: mouse_position = event.pos() topbar_rect = QRect(0, 0, self.width(), 10) if self.rect().adjusted(0, 10, 0, -10).contains(mouse_position): self.setCursor(Qt.ArrowCursor) elif topbar_rect.contains(mouse_position): self.setCursor(self.cursors.resize_top) else: self.setCursor(self.cursors.resize_bottom)
def adjustPosition(self, p): rect = self.rect() screen = QApplication.desktop().screenGeometry(self.getToolTipScreen()) if p.x() + rect.width() > screen.x() + screen.width(): # p.rx() -= 4 + rect.width() p.setX(p.x() - 4 + rect.width()) if p.y() + rect.height() > screen.y() + screen.height(): # p.ry() -= 24 + rect.height () p.setY(p.x() - 24 + rect.height()) if p.y() < screen.y(): p.setY(screen.y()) if p.x() + rect.width() > screen.x() + screen.width(): p.setX(screen.x() + screen.width() - rect.width()) if p.x() < screen.x(): p.setX(screen.x()) if p.y() + rect.height() > screen.y() + screen.height(): p.setY(screen.y() + screen.height() - rect.height()) futureRect = QRect(p.x(), p.y(), rect.width(), rect.height()) cursor = QCursor.pos() if futureRect.contains(cursor): offset = QPoint() diff = cursor.x() - futureRect.left() minDiff = diff offset = QPoint(diff + abs(self.cursorOffset.x()) + 1, 0) diff = futureRect.right() - cursor.x() if diff < minDiff: minDiff = diff offset = QPoint(-diff - abs(self.cursorOffset.x()) - 1, 0) diff = cursor.y() - futureRect.top() if diff < minDiff: minDiff = diff offset = QPoint(0, diff + abs(self.cursorOffset.y()) + 1) diff = futureRect.bottom() - cursor.y() if diff < minDiff: minDiff = diff offset = QPoint(0, -diff - abs(self.cursorOffset.y()) - 1) p += offset assert not QRect(p.x(), p.y(), rect.width(), rect.height()).contains(cursor) return p
def mousePressEvent(self, event): self.mousePressed.emit(event.pos()) # 鼠标点击事件 if event.button() == Qt.LeftButton: flag = windowManageWorker.windowMode if flag == "Full": x = self.quickItems['mainTitleBar'].x() y = self.quickItems['mainTitleBar'].y() width = self.quickItems['mainTitleBar'].width() height = self.quickItems['mainTitleBar'].height() rect = QRect(x, y, width, height) if rect.contains(event.pos()): self.dragPosition = event.globalPos() - \ self.frameGeometry().topLeft() elif flag == "Simple": x = self.rootObject().x() y = self.rootObject().y() width = self.rootObject().width() height = 40 rect = QRect(x, y, width, height) if rect.contains(event.pos()): self.dragPosition = event.globalPos() - \ self.frameGeometry().topLeft() super(MainWindow, self).mousePressEvent(event)
def wheelEvent(self,event): if not self.bCtrlPress: return self.rectList.clear() x = self.showImgLabel.geometry().x() + self.MidLayout.geometry().x() y = self.showImgLabel.geometry().y() + self.MidLayout.geometry().y() w,h = self.showImgLabel.geometry().width(),self.showImgLabel.geometry().height() qrect = QRect(QPoint(x,y),QSize(w,h)) if qrect.contains(event.pos()): delta = event.angleDelta() numDegress = delta.y()/8 if numDegress > 0: self.scale *= 1.2 else: self.scale /= 1.2 self.showImage()
def mouseMoveEvent(self, event: QMouseEvent) -> None: """ Sets the tooltip depending on the position of the mouse. """ if self.menu is None: # Relevant only for photo and video destination panels, not the combined # storage space display. return if self.display_type == DestinationDisplayType.folders_and_usage: # make tooltip different when hovering above storage space compared # to when hovering above the destination folder headerRect = QRect(0, 0, self.width(), self.deviceDisplay.dc.device_name_height) if not headerRect.contains(event.pos()): if (self.tooltip_display_state != DestinationDisplayTooltipState.storage_space): # Display tooltip for storage space self.setToolTip(self.projected_space_msg) self.tooltip_display_state = ( DestinationDisplayTooltipState.storage_space) self.update() return iconRect = self.deviceDisplay.menu_button_rect(0, 0, self.width()) if iconRect.contains(event.pos()): if self.mouse_pos == DestinationDisplayMousePos.normal: self.mouse_pos = DestinationDisplayMousePos.menu if self.file_type == FileType.photo: self.setToolTip(_("Configure photo subfolder creation")) else: self.setToolTip(_("Configure video subfolder creation")) self.tooltip_display_state = DestinationDisplayTooltipState.menu self.update() else: if (self.mouse_pos == DestinationDisplayMousePos.menu or self.tooltip_display_state != DestinationDisplayTooltipState.path): self.mouse_pos = DestinationDisplayMousePos.normal self.setToolTip(self.tool_tip) self.tooltip_display_state = DestinationDisplayTooltipState.path self.update()
class Node(): def __init__(self, Location): self.Location = Location self.regularColor = QColor(255, 255, 255) self.color = self.regularColor self.highlightColor = QColor(255, 255, 0) self.x = 0 self.y = 0 self.nodeSize = 6 self.boundingBox = QRect(self.x, self.y, self.nodeSize, self.nodeSize) def drawNode(self, qp, parent): if (self.Location == 'N'): self.x = parent.boundingBox.left( ) + parent.boundingBox.width() / 2 - self.nodeSize / 2 self.y = parent.boundingBox.top() #- self.nodeSize/2 self.boundingBox = QRect(self.x, self.y, self.nodeSize, self.nodeSize) if (self.Location == 'S'): self.x = parent.boundingBox.left( ) + parent.boundingBox.width() / 2 - self.nodeSize / 2 self.y = self.y = parent.boundingBox.bottom() - self.nodeSize + 1 self.boundingBox = QRect(self.x, self.y, self.nodeSize, self.nodeSize) if (self.Location == 'W'): self.x = parent.boundingBox.left() self.y = parent.boundingBox.top( ) + parent.boundingBox.height() / 2 - self.nodeSize / 2 self.boundingBox = QRect(self.x, self.y, self.nodeSize, self.nodeSize) if (self.Location == 'E'): self.x = parent.boundingBox.right() - self.nodeSize self.y = parent.boundingBox.top( ) + parent.boundingBox.height() / 2 - self.nodeSize / 2 self.boundingBox = QRect(self.x, self.y, self.nodeSize, self.nodeSize) qp.setBrush(self.color) qp.drawRect(self.boundingBox) def overObject(self, x, y): if self.boundingBox.contains(x, y): self.color = self.highlightColor return True else: self.color = self.regularColor return False
def mousePressEvent(self, event): if event.type() == QEvent.MouseButtonPress: self.set_icon(pressed=True) # figure out press location topRight = self.rect().topRight() bottomRight = self.rect().bottomRight() # get the rect from QStyle instead of hardcode numbers here arrowTopLeft = QPoint(topRight.x()-19, topRight.y()) arrowRect = QRect(arrowTopLeft, bottomRight) if arrowRect.contains(event.pos()) | (not self.divide): self.clicked_near_arrow = True self.blockSignals(True) QPushButton.mousePressEvent(self, event) self.blockSignals(False) self.open_context_menu() else: self.clicked_near_arrow = False QPushButton.mousePressEvent(self, event)
def is_visible(self, mainframe): """Check if the given element is visible in the given frame.""" self._check_vanished() # CSS attributes which hide an element hidden_attributes = { 'visibility': 'hidden', 'display': 'none', } for k, v in hidden_attributes.items(): if self._elem.styleProperty(k, QWebElement.ComputedStyle) == v: return False elem_geometry = self._elem.geometry() if not elem_geometry.isValid() and elem_geometry.x() == 0: # Most likely an invisible link return False # First check if the element is visible on screen elem_rect = self.rect_on_view(elem_geometry=elem_geometry) mainframe_geometry = mainframe.geometry() if elem_rect.isValid(): visible_on_screen = mainframe_geometry.intersects(elem_rect) else: # We got an invalid rectangle (width/height 0/0 probably), but this # can still be a valid link. visible_on_screen = mainframe_geometry.contains( elem_rect.topLeft()) # Then check if it's visible in its frame if it's not in the main # frame. elem_frame = self._elem.webFrame() framegeom = QRect(elem_frame.geometry()) if not framegeom.isValid(): visible_in_frame = False elif elem_frame.parentFrame() is not None: framegeom.moveTo(0, 0) framegeom.translate(elem_frame.scrollPosition()) if elem_geometry.isValid(): visible_in_frame = framegeom.intersects(elem_geometry) else: # We got an invalid rectangle (width/height 0/0 probably), but # this can still be a valid link. visible_in_frame = framegeom.contains(elem_geometry.topLeft()) else: visible_in_frame = visible_on_screen return all([visible_on_screen, visible_in_frame])
def __containsRemoveIcon(self, pos): """ Private method to check, if the given position is inside the remove icon. @param pos position to check for (QPoint) @return flag indicating success (boolean) """ itm = self.itemAt(pos) if itm is None: return False rect = self.visualItemRect(itm) iconSize = GreaseMonkeyConfigurationListDelegate.RemoveIconSize removeIconXPos = rect.right() - self.__delegate.padding() - iconSize center = rect.height() // 2 + rect.top() removeIconYPos = center - iconSize // 2 removeIconRect = QRect(removeIconXPos, removeIconYPos, iconSize, iconSize) return removeIconRect.contains(pos)
class SnapshotRegionGrabber(QWidget): """ Class implementing a grabber widget for a rectangular snapshot region. @signal grabbed(QPixmap) emitted after the region was grabbed """ grabbed = pyqtSignal(QPixmap) StrokeMask = 0 FillMask = 1 Rectangle = 0 Ellipse = 1 def __init__(self, mode=Rectangle): """ Constructor @param mode region grabber mode (SnapshotRegionGrabber.Rectangle or SnapshotRegionGrabber.Ellipse) """ super(SnapshotRegionGrabber, self).__init__( None, Qt.X11BypassWindowManagerHint | Qt.WindowStaysOnTopHint | Qt.FramelessWindowHint | Qt.Tool) assert mode in [SnapshotRegionGrabber.Rectangle, SnapshotRegionGrabber.Ellipse] self.__mode = mode self.__selection = QRect() self.__mouseDown = False self.__newSelection = False self.__handleSize = 10 self.__mouseOverHandle = None self.__showHelp = True self.__grabbing = False self.__dragStartPoint = QPoint() self.__selectionBeforeDrag = QRect() # naming conventions for handles # T top, B bottom, R Right, L left # 2 letters: a corner # 1 letter: the handle on the middle of the corresponding side self.__TLHandle = QRect(0, 0, self.__handleSize, self.__handleSize) self.__TRHandle = QRect(0, 0, self.__handleSize, self.__handleSize) self.__BLHandle = QRect(0, 0, self.__handleSize, self.__handleSize) self.__BRHandle = QRect(0, 0, self.__handleSize, self.__handleSize) self.__LHandle = QRect(0, 0, self.__handleSize, self.__handleSize) self.__THandle = QRect(0, 0, self.__handleSize, self.__handleSize) self.__RHandle = QRect(0, 0, self.__handleSize, self.__handleSize) self.__BHandle = QRect(0, 0, self.__handleSize, self.__handleSize) self.__handles = [self.__TLHandle, self.__TRHandle, self.__BLHandle, self.__BRHandle, self.__LHandle, self.__THandle, self.__RHandle, self.__BHandle] self.__helpTextRect = QRect() self.__helpText = self.tr( "Select a region using the mouse. To take the snapshot, press" " the Enter key or double click. Press Esc to quit.") self.__pixmap = QPixmap() self.setMouseTracking(True) QTimer.singleShot(200, self.__initialize) def __initialize(self): """ Private slot to initialize the rest of the widget. """ self.__desktop = QApplication.desktop() x = self.__desktop.x() y = self.__desktop.y() if qVersion() >= "5.0.0": self.__pixmap = QApplication.screens()[0].grabWindow( self.__desktop.winId(), x, y, self.__desktop.width(), self.__desktop.height()) else: self.__pixmap = QPixmap.grabWindow( self.__desktop.winId(), x, y, self.__desktop.width(), self.__desktop.height()) self.resize(self.__pixmap.size()) self.move(x, y) self.setCursor(Qt.CrossCursor) self.show() self.grabMouse() self.grabKeyboard() def paintEvent(self, evt): """ Protected method handling paint events. @param evt paint event (QPaintEvent) """ if self.__grabbing: # grabWindow() should just get the background return painter = QPainter(self) pal = QPalette(QToolTip.palette()) font = QToolTip.font() handleColor = pal.color(QPalette.Active, QPalette.Highlight) handleColor.setAlpha(160) overlayColor = QColor(0, 0, 0, 160) textColor = pal.color(QPalette.Active, QPalette.Text) textBackgroundColor = pal.color(QPalette.Active, QPalette.Base) painter.drawPixmap(0, 0, self.__pixmap) painter.setFont(font) r = QRect(self.__selection) if not self.__selection.isNull(): grey = QRegion(self.rect()) if self.__mode == SnapshotRegionGrabber.Ellipse: reg = QRegion(r, QRegion.Ellipse) else: reg = QRegion(r) grey = grey.subtracted(reg) painter.setClipRegion(grey) painter.setPen(Qt.NoPen) painter.setBrush(overlayColor) painter.drawRect(self.rect()) painter.setClipRect(self.rect()) drawRect(painter, r, handleColor) if self.__showHelp: painter.setPen(textColor) painter.setBrush(textBackgroundColor) self.__helpTextRect = painter.boundingRect( self.rect().adjusted(2, 2, -2, -2), Qt.TextWordWrap, self.__helpText).translated( -self.__desktop.x(), -self.__desktop.y()) self.__helpTextRect.adjust(-2, -2, 4, 2) drawRect(painter, self.__helpTextRect, textColor, textBackgroundColor) painter.drawText( self.__helpTextRect.adjusted(3, 3, -3, -3), Qt.TextWordWrap, self.__helpText) if self.__selection.isNull(): return # The grabbed region is everything which is covered by the drawn # rectangles (border included). This means that there is no 0px # selection, since a 0px wide rectangle will always be drawn as a line. txt = "{0:n}, {1:n} ({2:n} x {3:n})".format( self.__selection.x(), self.__selection.y(), self.__selection.width(), self.__selection.height()) textRect = painter.boundingRect(self.rect(), Qt.AlignLeft, txt) boundingRect = textRect.adjusted(-4, 0, 0, 0) if textRect.width() < r.width() - 2 * self.__handleSize and \ textRect.height() < r.height() - 2 * self.__handleSize and \ r.width() > 100 and \ r.height() > 100: # center, unsuitable for small selections boundingRect.moveCenter(r.center()) textRect.moveCenter(r.center()) elif r.y() - 3 > textRect.height() and \ r.x() + textRect.width() < self.rect().width(): # on top, left aligned boundingRect.moveBottomLeft(QPoint(r.x(), r.y() - 3)) textRect.moveBottomLeft(QPoint(r.x() + 2, r.y() - 3)) elif r.x() - 3 > textRect.width(): # left, top aligned boundingRect.moveTopRight(QPoint(r.x() - 3, r.y())) textRect.moveTopRight(QPoint(r.x() - 5, r.y())) elif r.bottom() + 3 + textRect.height() < self.rect().bottom() and \ r.right() > textRect.width(): # at bottom, right aligned boundingRect.moveTopRight(QPoint(r.right(), r.bottom() + 3)) textRect.moveTopRight(QPoint(r.right() - 2, r.bottom() + 3)) elif r.right() + textRect.width() + 3 < self.rect().width(): # right, bottom aligned boundingRect.moveBottomLeft(QPoint(r.right() + 3, r.bottom())) textRect.moveBottomLeft(QPoint(r.right() + 5, r.bottom())) # If the above didn't catch it, you are running on a very # tiny screen... drawRect(painter, boundingRect, textColor, textBackgroundColor) painter.drawText(textRect, Qt.AlignHCenter, txt) if (r.height() > self.__handleSize * 2 and r.width() > self.__handleSize * 2) or \ not self.__mouseDown: self.__updateHandles() painter.setPen(Qt.NoPen) painter.setBrush(handleColor) painter.setClipRegion( self.__handleMask(SnapshotRegionGrabber.StrokeMask)) painter.drawRect(self.rect()) handleColor.setAlpha(60) painter.setBrush(handleColor) painter.setClipRegion( self.__handleMask(SnapshotRegionGrabber.FillMask)) painter.drawRect(self.rect()) def resizeEvent(self, evt): """ Protected method to handle resize events. @param evt resize event (QResizeEvent) """ if self.__selection.isNull(): return r = QRect(self.__selection) r.setTopLeft(self.__limitPointToRect(r.topLeft(), self.rect())) r.setBottomRight(self.__limitPointToRect(r.bottomRight(), self.rect())) if r.width() <= 1 or r.height() <= 1: # This just results in ugly drawing... self.__selection = QRect() else: self.__selection = self.__normalizeSelection(r) def mousePressEvent(self, evt): """ Protected method to handle mouse button presses. @param evt mouse press event (QMouseEvent) """ self.__showHelp = not self.__helpTextRect.contains(evt.pos()) if evt.button() == Qt.LeftButton: self.__mouseDown = True self.__dragStartPoint = evt.pos() self.__selectionBeforeDrag = QRect(self.__selection) if not self.__selection.contains(evt.pos()): self.__newSelection = True self.__selection = QRect() else: self.setCursor(Qt.ClosedHandCursor) elif evt.button() == Qt.RightButton: self.__newSelection = False self.__selection = QRect() self.setCursor(Qt.CrossCursor) self.update() def mouseMoveEvent(self, evt): """ Protected method to handle mouse movements. @param evt mouse move event (QMouseEvent) """ shouldShowHelp = not self.__helpTextRect.contains(evt.pos()) if shouldShowHelp != self.__showHelp: self.__showHelp = shouldShowHelp self.update() if self.__mouseDown: if self.__newSelection: p = evt.pos() r = self.rect() self.__selection = self.__normalizeSelection( QRect(self.__dragStartPoint, self.__limitPointToRect(p, r))) elif self.__mouseOverHandle is None: # moving the whole selection r = self.rect().normalized() s = self.__selectionBeforeDrag.normalized() p = s.topLeft() + evt.pos() - self.__dragStartPoint r.setBottomRight( r.bottomRight() - QPoint(s.width(), s.height()) + QPoint(1, 1)) if not r.isNull() and r.isValid(): self.__selection.moveTo(self.__limitPointToRect(p, r)) else: # dragging a handle r = QRect(self.__selectionBeforeDrag) offset = evt.pos() - self.__dragStartPoint if self.__mouseOverHandle in \ [self.__TLHandle, self.__THandle, self.__TRHandle]: r.setTop(r.top() + offset.y()) if self.__mouseOverHandle in \ [self.__TLHandle, self.__LHandle, self.__BLHandle]: r.setLeft(r.left() + offset.x()) if self.__mouseOverHandle in \ [self.__BLHandle, self.__BHandle, self.__BRHandle]: r.setBottom(r.bottom() + offset.y()) if self.__mouseOverHandle in \ [self.__TRHandle, self.__RHandle, self.__BRHandle]: r.setRight(r.right() + offset.x()) r.setTopLeft(self.__limitPointToRect(r.topLeft(), self.rect())) r.setBottomRight( self.__limitPointToRect(r.bottomRight(), self.rect())) self.__selection = self.__normalizeSelection(r) self.update() else: if self.__selection.isNull(): return found = False for r in self.__handles: if r.contains(evt.pos()): self.__mouseOverHandle = r found = True break if not found: self.__mouseOverHandle = None if self.__selection.contains(evt.pos()): self.setCursor(Qt.OpenHandCursor) else: self.setCursor(Qt.CrossCursor) else: if self.__mouseOverHandle in [self.__TLHandle, self.__BRHandle]: self.setCursor(Qt.SizeFDiagCursor) elif self.__mouseOverHandle in [self.__TRHandle, self.__BLHandle]: self.setCursor(Qt.SizeBDiagCursor) elif self.__mouseOverHandle in [self.__LHandle, self.__RHandle]: self.setCursor(Qt.SizeHorCursor) elif self.__mouseOverHandle in [self.__THandle, self.__BHandle]: self.setCursor(Qt.SizeVerCursor) def mouseReleaseEvent(self, evt): """ Protected method to handle mouse button releases. @param evt mouse release event (QMouseEvent) """ self.__mouseDown = False self.__newSelection = False if self.__mouseOverHandle is None and \ self.__selection.contains(evt.pos()): self.setCursor(Qt.OpenHandCursor) self.update() def mouseDoubleClickEvent(self, evt): """ Protected method to handle mouse double clicks. @param evt mouse double click event (QMouseEvent) """ self.__grabRect() def keyPressEvent(self, evt): """ Protected method to handle key presses. @param evt key press event (QKeyEvent) """ if evt.key() == Qt.Key_Escape: self.grabbed.emit(QPixmap()) elif evt.key() in [Qt.Key_Enter, Qt.Key_Return]: self.__grabRect() else: evt.ignore() def __updateHandles(self): """ Private method to update the handles. """ r = QRect(self.__selection) s2 = self.__handleSize // 2 self.__TLHandle.moveTopLeft(r.topLeft()) self.__TRHandle.moveTopRight(r.topRight()) self.__BLHandle.moveBottomLeft(r.bottomLeft()) self.__BRHandle.moveBottomRight(r.bottomRight()) self.__LHandle.moveTopLeft(QPoint(r.x(), r.y() + r.height() // 2 - s2)) self.__THandle.moveTopLeft(QPoint(r.x() + r.width() // 2 - s2, r.y())) self.__RHandle.moveTopRight( QPoint(r.right(), r.y() + r.height() // 2 - s2)) self.__BHandle.moveBottomLeft( QPoint(r.x() + r.width() // 2 - s2, r.bottom())) def __handleMask(self, maskType): """ Private method to calculate the handle mask. @param maskType type of the mask to be used (SnapshotRegionGrabber.FillMask or SnapshotRegionGrabber.StrokeMask) @return calculated mask (QRegion) """ mask = QRegion() for rect in self.__handles: if maskType == SnapshotRegionGrabber.StrokeMask: r = QRegion(rect) mask += r.subtracted(QRegion(rect.adjusted(1, 1, -1, -1))) else: mask += QRegion(rect.adjusted(1, 1, -1, -1)) return mask def __limitPointToRect(self, point, rect): """ Private method to limit the given point to the given rectangle. @param point point to be limited (QPoint) @param rect rectangle the point shall be limited to (QRect) @return limited point (QPoint) """ q = QPoint() if point.x() < rect.x(): q.setX(rect.x()) elif point.x() < rect.right(): q.setX(point.x()) else: q.setX(rect.right()) if point.y() < rect.y(): q.setY(rect.y()) elif point.y() < rect.bottom(): q.setY(point.y()) else: q.setY(rect.bottom()) return q def __normalizeSelection(self, sel): """ Private method to normalize the given selection. @param sel selection to be normalized (QRect) @return normalized selection (QRect) """ rect = QRect(sel) if rect.width() <= 0: left = rect.left() width = rect.width() rect.setLeft(left + width - 1) rect.setRight(left) if rect.height() <= 0: top = rect.top() height = rect.height() rect.setTop(top + height - 1) rect.setBottom(top) return rect def __grabRect(self): """ Private method to grab the selected rectangle (i.e. do the snapshot). """ if self.__mode == SnapshotRegionGrabber.Ellipse: ell = QRegion(self.__selection, QRegion.Ellipse) if not ell.isEmpty(): self.__grabbing = True xOffset = self.__pixmap.rect().x() - ell.boundingRect().x() yOffset = self.__pixmap.rect().y() - ell.boundingRect().y() translatedEll = ell.translated(xOffset, yOffset) pixmap2 = QPixmap(ell.boundingRect().size()) pixmap2.fill(Qt.transparent) pt = QPainter() pt.begin(pixmap2) if pt.paintEngine().hasFeature(QPaintEngine.PorterDuff): pt.setRenderHints( QPainter.Antialiasing | QPainter.HighQualityAntialiasing | QPainter.SmoothPixmapTransform, True) pt.setBrush(Qt.black) pt.setPen(QPen(QBrush(Qt.black), 0.5)) pt.drawEllipse(translatedEll.boundingRect()) pt.setCompositionMode(QPainter.CompositionMode_SourceIn) else: pt.setClipRegion(translatedEll) pt.setCompositionMode(QPainter.CompositionMode_Source) pt.drawPixmap(pixmap2.rect(), self.__pixmap, ell.boundingRect()) pt.end() self.grabbed.emit(pixmap2) else: r = QRect(self.__selection) if not r.isNull() and r.isValid(): self.__grabbing = True self.grabbed.emit(self.__pixmap.copy(r))
class PanelTopLeftCorner(QWidget): def __init__(self, parent): super(QWidget, self).__init__(parent) self.menuRect = QRect(4, 4, 14, 14) self.hovered = False self.panelMenu = QMenu() if 0 else None self.setMouseTracking(True) self.setAttribute(Qt.WA_Hover) self.installEventFilter(self) def minimumSizeHint(self): return QSize(22, 22) def sizeHint(self): return self.minimumSizeHint() def paintEvent(self, event): painter = QPainter(self) palette = self.palette() midColor = palette.mid().color() highlight = palette.highlight().color() # background painter.fillRect(self.rect(), midColor.lighter()) # menu rect color = highlight if self.hovered else midColor painter.setPen(color) painter.setBrush(palette.light()) painter.drawRect(self.menuRect) if color == highlight: painter.setBrush(highlight) painter.drawRect(self.menuRect.adjusted(2, 2, -2, -2)) def mouseMoveEvent(self, event): self.hovered = self.menuRect.contains(event.pos()) self.repaint(self.menuRect.adjusted(-1, -1, -1, -1)) def mousePressEvent(self, event): mouseClickPos = event.pos() if self.menuRect.contains(mouseClickPos): self.panelMenu.exec_(self.mapToGlobal(mouseClickPos)) def eventFilter(self, obj, event): if event.type() == QEvent.HoverLeave: self.hovered = False self.repaint(self.rect()) return True return False def createMenu(self, items): self.panelMenu = QMenu(self) for item in items: self.panelMenu.addAction(item) self.panelMenu.addSeparator() self.panelMenu.addAction('Close Tab') self.panelMenu.aboutToHide.connect(lambda: self.menuAboutToHide()) return self.panelMenu def contextMenuEvent(self, event): pos = event.pos() if self.panelMenu and self.menuRect.contains(pos): self.panelMenu.exec_(self.mapToGlobal(pos)) event.accept() def menuAboutToHide(self): self.hovered = False self.repaint(self.menuRect.adjusted(-1, -1, 1, 1))
class SnapshotFreehandGrabber(QWidget): """ Class implementing a grabber widget for a freehand snapshot region. @signal grabbed(QPixmap) emitted after the region was grabbed """ grabbed = pyqtSignal(QPixmap) def __init__(self): """ Constructor """ super(SnapshotFreehandGrabber, self).__init__( None, Qt.X11BypassWindowManagerHint | Qt.WindowStaysOnTopHint | Qt.FramelessWindowHint | Qt.Tool) self.__selection = QPolygon() self.__mouseDown = False self.__newSelection = False self.__handleSize = 10 self.__showHelp = True self.__grabbing = False self.__dragStartPoint = QPoint() self.__selectionBeforeDrag = QPolygon() self.__locale = QLocale() self.__helpTextRect = QRect() self.__helpText = self.tr( "Select a region using the mouse. To take the snapshot," " press the Enter key or double click. Press Esc to quit.") self.__pixmap = QPixmap() self.__pBefore = QPoint() self.setMouseTracking(True) QTimer.singleShot(200, self.__initialize) def __initialize(self): """ Private slot to initialize the rest of the widget. """ self.__desktop = QApplication.desktop() x = self.__desktop.x() y = self.__desktop.y() if qVersion() >= "5.0.0": self.__pixmap = QApplication.screens()[0].grabWindow( self.__desktop.winId(), x, y, self.__desktop.width(), self.__desktop.height()) else: self.__pixmap = QPixmap.grabWindow( self.__desktop.winId(), x, y, self.__desktop.width(), self.__desktop.height()) self.resize(self.__pixmap.size()) self.move(x, y) self.setCursor(Qt.CrossCursor) self.show() self.grabMouse() self.grabKeyboard() self.activateWindow() def paintEvent(self, evt): """ Protected method handling paint events. @param evt paint event (QPaintEvent) """ if self.__grabbing: # grabWindow() should just get the background return painter = QPainter(self) pal = QPalette(QToolTip.palette()) font = QToolTip.font() handleColor = pal.color(QPalette.Active, QPalette.Highlight) handleColor.setAlpha(160) overlayColor = QColor(0, 0, 0, 160) textColor = pal.color(QPalette.Active, QPalette.Text) textBackgroundColor = pal.color(QPalette.Active, QPalette.Base) painter.drawPixmap(0, 0, self.__pixmap) painter.setFont(font) pol = QPolygon(self.__selection) if not self.__selection.boundingRect().isNull(): # Draw outline around selection. # Important: the 1px-wide outline is *also* part of the # captured free-region pen = QPen(handleColor, 1, Qt.SolidLine, Qt.SquareCap, Qt.BevelJoin) painter.setPen(pen) painter.drawPolygon(pol) # Draw the grey area around the selection. grey = QRegion(self.rect()) grey = grey - QRegion(pol) painter.setClipRegion(grey) painter.setPen(Qt.NoPen) painter.setBrush(overlayColor) painter.drawRect(self.rect()) painter.setClipRect(self.rect()) drawPolygon(painter, pol, handleColor) if self.__showHelp: painter.setPen(textColor) painter.setBrush(textBackgroundColor) self.__helpTextRect = painter.boundingRect( self.rect().adjusted(2, 2, -2, -2), Qt.TextWordWrap, self.__helpText).translated( -self.__desktop.x(), -self.__desktop.y()) self.__helpTextRect.adjust(-2, -2, 4, 2) drawPolygon(painter, self.__helpTextRect, textColor, textBackgroundColor) painter.drawText( self.__helpTextRect.adjusted(3, 3, -3, -3), Qt.TextWordWrap, self.__helpText) if self.__selection.isEmpty(): return # The grabbed region is everything which is covered by the drawn # rectangles (border included). This means that there is no 0px # selection, since a 0px wide rectangle will always be drawn as a line. boundingRect = self.__selection.boundingRect() txt = "{0}, {1} ({2} x {3})".format( self.__locale.toString(boundingRect.x()), self.__locale.toString(boundingRect.y()), self.__locale.toString(boundingRect.width()), self.__locale.toString(boundingRect.height()) ) textRect = painter.boundingRect(self.rect(), Qt.AlignLeft, txt) boundingRect = textRect.adjusted(-4, 0, 0, 0) polBoundingRect = pol.boundingRect() if (textRect.width() < polBoundingRect.width() - 2 * self.__handleSize) and \ (textRect.height() < polBoundingRect.height() - 2 * self.__handleSize) and \ polBoundingRect.width() > 100 and \ polBoundingRect.height() > 100: # center, unsuitable for small selections boundingRect.moveCenter(polBoundingRect.center()) textRect.moveCenter(polBoundingRect.center()) elif polBoundingRect.y() - 3 > textRect.height() and \ polBoundingRect.x() + textRect.width() < self.rect().width(): # on top, left aligned boundingRect.moveBottomLeft( QPoint(polBoundingRect.x(), polBoundingRect.y() - 3)) textRect.moveBottomLeft( QPoint(polBoundingRect.x() + 2, polBoundingRect.y() - 3)) elif polBoundingRect.x() - 3 > textRect.width(): # left, top aligned boundingRect.moveTopRight( QPoint(polBoundingRect.x() - 3, polBoundingRect.y())) textRect.moveTopRight( QPoint(polBoundingRect.x() - 5, polBoundingRect.y())) elif (polBoundingRect.bottom() + 3 + textRect.height() < self.rect().bottom()) and \ polBoundingRect.right() > textRect.width(): # at bottom, right aligned boundingRect.moveTopRight( QPoint(polBoundingRect.right(), polBoundingRect.bottom() + 3)) textRect.moveTopRight( QPoint(polBoundingRect.right() - 2, polBoundingRect.bottom() + 3)) elif polBoundingRect.right() + textRect.width() + 3 < \ self.rect().width(): # right, bottom aligned boundingRect.moveBottomLeft( QPoint(polBoundingRect.right() + 3, polBoundingRect.bottom())) textRect.moveBottomLeft( QPoint(polBoundingRect.right() + 5, polBoundingRect.bottom())) # If the above didn't catch it, you are running on a very # tiny screen... drawPolygon(painter, boundingRect, textColor, textBackgroundColor) painter.drawText(textRect, Qt.AlignHCenter, txt) if (polBoundingRect.height() > self.__handleSize * 2 and polBoundingRect.width() > self.__handleSize * 2) or \ not self.__mouseDown: painter.setBrush(Qt.transparent) painter.setClipRegion(QRegion(pol)) painter.drawPolygon(QPolygon(self.rect())) def mousePressEvent(self, evt): """ Protected method to handle mouse button presses. @param evt mouse press event (QMouseEvent) """ self.__pBefore = evt.pos() self.__showHelp = not self.__helpTextRect.contains(evt.pos()) if evt.button() == Qt.LeftButton: self.__mouseDown = True self.__dragStartPoint = evt.pos() self.__selectionBeforeDrag = QPolygon(self.__selection) if not self.__selection.containsPoint(evt.pos(), Qt.WindingFill): self.__newSelection = True self.__selection = QPolygon() else: self.setCursor(Qt.ClosedHandCursor) elif evt.button() == Qt.RightButton: self.__newSelection = False self.__selection = QPolygon() self.setCursor(Qt.CrossCursor) self.update() def mouseMoveEvent(self, evt): """ Protected method to handle mouse movements. @param evt mouse move event (QMouseEvent) """ shouldShowHelp = not self.__helpTextRect.contains(evt.pos()) if shouldShowHelp != self.__showHelp: self.__showHelp = shouldShowHelp self.update() if self.__mouseDown: if self.__newSelection: p = evt.pos() self.__selection.append(p) else: # moving the whole selection p = evt.pos() - self.__pBefore # Offset self.__pBefore = evt.pos() # save position for next iteration self.__selection.translate(p) self.update() else: if self.__selection.boundingRect().isEmpty(): return if self.__selection.containsPoint(evt.pos(), Qt.WindingFill): self.setCursor(Qt.OpenHandCursor) else: self.setCursor(Qt.CrossCursor) def mouseReleaseEvent(self, evt): """ Protected method to handle mouse button releases. @param evt mouse release event (QMouseEvent) """ self.__mouseDown = False self.__newSelection = False if self.__selection.containsPoint(evt.pos(), Qt.WindingFill): self.setCursor(Qt.OpenHandCursor) self.update() def mouseDoubleClickEvent(self, evt): """ Protected method to handle mouse double clicks. @param evt mouse double click event (QMouseEvent) """ self.__grabRegion() def keyPressEvent(self, evt): """ Protected method to handle key presses. @param evt key press event (QKeyEvent) """ if evt.key() == Qt.Key_Escape: self.grabbed.emit(QPixmap()) elif evt.key() in [Qt.Key_Enter, Qt.Key_Return]: self.__grabRegion() else: evt.ignore() def __grabRegion(self): """ Private method to grab the selected region (i.e. do the snapshot). """ pol = QPolygon(self.__selection) if not pol.isEmpty(): self.__grabbing = True xOffset = self.__pixmap.rect().x() - pol.boundingRect().x() yOffset = self.__pixmap.rect().y() - pol.boundingRect().y() translatedPol = pol.translated(xOffset, yOffset) pixmap2 = QPixmap(pol.boundingRect().size()) pixmap2.fill(Qt.transparent) pt = QPainter() pt.begin(pixmap2) if pt.paintEngine().hasFeature(QPaintEngine.PorterDuff): pt.setRenderHints( QPainter.Antialiasing | QPainter.HighQualityAntialiasing | QPainter.SmoothPixmapTransform, True) pt.setBrush(Qt.black) pt.setPen(QPen(QBrush(Qt.black), 0.5)) pt.drawPolygon(translatedPol) pt.setCompositionMode(QPainter.CompositionMode_SourceIn) else: pt.setClipRegion(QRegion(translatedPol)) pt.setCompositionMode(QPainter.CompositionMode_Source) pt.drawPixmap(pixmap2.rect(), self.__pixmap, pol.boundingRect()) pt.end() self.grabbed.emit(pixmap2)
class TriblerButtonsDelegate(QStyledItemDelegate): redraw_required = pyqtSignal() def __init__(self, parent=None): QStyledItemDelegate.__init__(self, parent) self.no_index = QModelIndex() self.hoverrow = None self.hover_index = None self.controls = [] # We have to control if mouse is in the buttons box to add some tolerance for vertical mouse # misplacement around the buttons. The button box effectively overlaps upper and lower rows. # row 0 # --------- <- tolerance zone # row 1 |buttons| # --------- <- tolerance zone # row 2 # button_box_extended_border_ration controls the thickness of the tolerance zone self.button_box = QRect() self.button_box_extended_border_ratio = float(0.3) def paint_empty_background(self, painter, option): super(TriblerButtonsDelegate, self).paint(painter, option, self.no_index) def on_mouse_moved(self, pos, index): # This method controls for which rows the buttons/box should be drawn redraw = False if self.hover_index != index: self.hover_index = index self.hoverrow = index.row() if not self.button_box.contains(pos): redraw = True # Redraw when the mouse leaves the table if index.row() == -1 and self.hoverrow != -1: self.hoverrow = -1 redraw = True for controls in self.controls: redraw = controls.on_mouse_moved(pos, index) or redraw if redraw: # TODO: optimize me to only redraw the rows that actually changed! self.redraw_required.emit() @staticmethod def split_rect_into_squares(rect, buttons): r = rect side_size = min(r.width() / len(buttons), r.height() - 2) y_border = (r.height() - side_size) / 2 for n, button in enumerate(buttons): x = r.left() + n * side_size y = r.top() + y_border h = side_size w = side_size yield QRect(x, y, w, h), button def paint(self, painter, option, index): # Draw 'hover' state highlight for every cell of a row if index.row() == self.hoverrow: option.state |= QStyle.State_MouseOver if not self.paint_exact(painter, option, index): # Draw the rest of the columns super(TriblerButtonsDelegate, self).paint(painter, option, index) @abstractmethod def paint_exact(self, painter, option, index): pass def editorEvent(self, event, model, option, index): for control in self.controls: result = control.check_clicked(event, model, option, index) if result: return result return False def createEditor(self, parent, option, index): # Add null editor to action buttons column if index.column() == index.model().column_position[ACTION_BUTTONS]: return if index.column() == index.model().column_position['category']: cbox = QComboBox(parent) cbox.addItems(CATEGORY_LIST) return cbox return super(TriblerButtonsDelegate, self).createEditor(parent, option, index)
def mouseMoveEvent(self, evt): """ Protected method to handle mouse movements. @param evt mouse move event (QMouseEvent) """ shouldShowHelp = not self.__helpTextRect.contains(evt.pos()) if shouldShowHelp != self.__showHelp: self.__showHelp = shouldShowHelp self.update() if self.__mouseDown: if self.__newSelection: p = evt.pos() r = self.rect() self.__selection = self.__normalizeSelection( QRect(self.__dragStartPoint, self.__limitPointToRect(p, r))) elif self.__mouseOverHandle is None: # moving the whole selection r = self.rect().normalized() s = self.__selectionBeforeDrag.normalized() p = s.topLeft() + evt.pos() - self.__dragStartPoint r.setBottomRight( r.bottomRight() - QPoint(s.width(), s.height()) + QPoint(1, 1)) if not r.isNull() and r.isValid(): self.__selection.moveTo(self.__limitPointToRect(p, r)) else: # dragging a handle r = QRect(self.__selectionBeforeDrag) offset = evt.pos() - self.__dragStartPoint if self.__mouseOverHandle in \ [self.__TLHandle, self.__THandle, self.__TRHandle]: r.setTop(r.top() + offset.y()) if self.__mouseOverHandle in \ [self.__TLHandle, self.__LHandle, self.__BLHandle]: r.setLeft(r.left() + offset.x()) if self.__mouseOverHandle in \ [self.__BLHandle, self.__BHandle, self.__BRHandle]: r.setBottom(r.bottom() + offset.y()) if self.__mouseOverHandle in \ [self.__TRHandle, self.__RHandle, self.__BRHandle]: r.setRight(r.right() + offset.x()) r.setTopLeft(self.__limitPointToRect(r.topLeft(), self.rect())) r.setBottomRight( self.__limitPointToRect(r.bottomRight(), self.rect())) self.__selection = self.__normalizeSelection(r) self.update() else: if self.__selection.isNull(): return found = False for r in self.__handles: if r.contains(evt.pos()): self.__mouseOverHandle = r found = True break if not found: self.__mouseOverHandle = None if self.__selection.contains(evt.pos()): self.setCursor(Qt.OpenHandCursor) else: self.setCursor(Qt.CrossCursor) else: if self.__mouseOverHandle in [self.__TLHandle, self.__BRHandle]: self.setCursor(Qt.SizeFDiagCursor) elif self.__mouseOverHandle in [self.__TRHandle, self.__BLHandle]: self.setCursor(Qt.SizeBDiagCursor) elif self.__mouseOverHandle in [self.__LHandle, self.__RHandle]: self.setCursor(Qt.SizeHorCursor) elif self.__mouseOverHandle in [self.__THandle, self.__BHandle]: self.setCursor(Qt.SizeVerCursor)
class PanelTopRightCorner(QWidget): def __init__(self, parent): super(QWidget, self).__init__(parent) self.vSplitRect = QRect() self.hSplitRect = QRect() self.floatRect = QRect() self.closeRect = QRect() self.closeClicked = pyqtSignal() self.floatClicked = pyqtSignal() self.splitClicked = pyqtSignal() self.mouseHoverState = MOUSE_HOVER.HOVER_NONE self.mouseClickPos = QPoint() self.setMouseTracking(True) self.setAttribute(Qt.WA_Hover) self.installEventFilter(self) def minimumSizeHint(self): w = 4 w += self.vSplitRect.width() + 6 w += self.hSplitRect.width() + 6 w += self.floatRect.width() + 6 w += self.closeRect.width() + 6 s = QSize(w, 22) return s def sizeHint(self): return self.minimumSizeHint() def mouseMoveEvent(self, event): p = event.pos() r = QRect() if self.vSplitRect.contains(p): self.mouseHoverState = MOUSE_HOVER.HOVER_VSPLIT elif self.hSplitRect.contains(p): self.mouseHoverState = MOUSE_HOVER.HOVER_HSPLIT elif self.closeRect.contains(p): self.mouseHoverState = MOUSE_HOVER.HOVER_CLOSE elif self.floatRect.contains(p): self.mouseHoverState = MOUSE_HOVER.HOVER_FLOAT else: self.mouseHoverState = MOUSE_HOVER.HOVER_NONE self.repaint(r.adjusted(-1, -1, 1, 1)) def mousePressEvent(self, event): self.mouseClickPos = event.pos() if self.closeRect.contains(self.mouseClickPos): self.closeClicked.emit() elif self.floatRect.contains(self.mouseClickPos): self.floatClicked.emit() elif self.vSplitRect.contains(self.mouseClickPos): self.splitClicked.emit(Qt.Vertical) elif self.hSplitRect.contains(self.mouseClickPos): self.splitClicked.emit(Qt.Horizontal) self.mouseHoverState = MOUSE_HOVER.HOVER_NONE def paintEvent(self, event): painter = QPainter(self) palette = self.palette() midColor = palette.mid().color() highlight = palette.highlight().color() # background painter.fillRect(self.rect(), midColor.lighter()) # float rect color = highlight if self.mouseHoverState == MOUSE_HOVER.HOVER_FLOAT else midColor painter.setPen(color) painter.setBrush(palette.light()) painter.drawRect(self.floatRect) painter.setBrush(highlight if color == highlight else midColor) painter.drawRect(self.floatRect.adjusted(4, 2, -2, -4)) # hsplit rect color = highlight if self.mouseHoverState == MOUSE_HOVER.HOVER_HSPLIT else midColor painter.setPen(color) painter.setBrush(palette.light()) painter.drawRect(self.hSplitRect) painter.setBrush(highlight if color == highlight else midColor) painter.drawRect(self.hSplitRect.adjusted(2, 2, -6, -2)) # float rect color = highlight if self.mouseHoverState == MOUSE_HOVER.HOVER_VSPLIT else midColor painter.setPen(color) painter.setBrush(palette.light()) painter.drawRect(self.vSplitRect) painter.setBrush(highlight if color == highlight else midColor) painter.drawRect(self.vSplitRect.adjusted(2, 2, -2, -6)) # float rect color = highlight if self.mouseHoverState == MOUSE_HOVER.HOVER_CLOSE else midColor painter.setPen(color) painter.setBrush(palette.light()) painter.drawRect(self.closeRect) painter.translate(self.closeRect.topLeft()) painter.setPen(QPen(color, 1.5)) painter.drawLine(QPoint(4, 4), QPoint(9, 9)) painter.drawLine(QPoint(4, 9), QPoint(9, 4)) painter.resetTransform() def resizeEvent(self, event): w = self.width() self.hSplitRect = QRect(w-72, 4, 12, 12) self.vSplitRect = QRect(w-54, 4, 12, 12) self.floatRect = QRect(w-36, 4, 12, 12) self.closeRect = QRect(w-18, 4, 12, 12) def eventFilter(self, obj, event): if event.type() == QEvent.HoverLeave: self.mouseHoverState = MOUSE_HOVER.HOVER_NONE self.repaint(self.rect()) return True return False
class corkDelegate(QStyledItemDelegate): def __init__(self, parent=None): QStyledItemDelegate.__init__(self, parent) self.factor = settings.corkSizeFactor / 100. self.defaultSize = QSize(300, 200) self.lastPos = None self.editing = None self.margin = 5 def setCorkSizeFactor(self, v): self.factor = v / 100. def sizeHint(self, option, index): return self.defaultSize * self.factor def editorEvent(self, event, model, option, index): # We catch the mouse position in the widget to know which part to edit if type(event) == QMouseEvent: self.lastPos = event.pos() # - option.rect.topLeft() return QStyledItemDelegate.editorEvent(self, event, model, option, index) def createEditor(self, parent, option, index): self.updateRects(option, index) if self.mainLineRect.contains(self.lastPos): # One line summary self.editing = Outline.summarySentance edt = QLineEdit(parent) edt.setFocusPolicy(Qt.StrongFocus) edt.setFrame(False) edt.setAlignment(Qt.AlignCenter) edt.setPlaceholderText(self.tr("One line summary")) f = QFont(option.font) f.setItalic(True) edt.setFont(f) return edt elif self.titleRect.contains(self.lastPos): # Title self.editing = Outline.title edt = QLineEdit(parent) edt.setFocusPolicy(Qt.StrongFocus) edt.setFrame(False) f = QFont(option.font) # f.setPointSize(f.pointSize() + 1) f.setBold(True) edt.setFont(f) edt.setAlignment(Qt.AlignCenter) # edt.setGeometry(self.titleRect) return edt else: # self.mainTextRect.contains(self.lastPos): # Summary self.editing = Outline.summaryFull edt = QPlainTextEdit(parent) edt.setFocusPolicy(Qt.StrongFocus) edt.setFrameShape(QFrame.NoFrame) edt.setPlaceholderText(self.tr("Full summary")) return edt def updateEditorGeometry(self, editor, option, index): if self.editing == Outline.summarySentance: # One line summary editor.setGeometry(self.mainLineRect) elif self.editing == Outline.title: # Title editor.setGeometry(self.titleRect) elif self.editing == Outline.summaryFull: # Summary editor.setGeometry(self.mainTextRect) def setEditorData(self, editor, index): item = index.internalPointer() if self.editing == Outline.summarySentance: # One line summary editor.setText(item.data(Outline.summarySentance.value)) elif self.editing == Outline.title: # Title editor.setText(index.data()) elif self.editing == Outline.summaryFull: # Summary editor.setPlainText(item.data(Outline.summaryFull.value)) def setModelData(self, editor, model, index): if self.editing == Outline.summarySentance: # One line summary model.setData(index.sibling(index.row(), Outline.summarySentance.value), editor.text()) elif self.editing == Outline.title: # Title model.setData(index, editor.text(), Outline.title.value) elif self.editing == Outline.summaryFull: # Summary model.setData(index.sibling(index.row(), Outline.summaryFull.value), editor.toPlainText()) def updateRects(self, option, index): margin = self.margin iconSize = max(16 * self.factor, 12) item = index.internalPointer() self.itemRect = option.rect.adjusted(margin, margin, -margin, -margin) self.iconRect = QRect(self.itemRect.topLeft() + QPoint(margin, margin), QSize(iconSize, iconSize)) self.labelRect = QRect(self.itemRect.topRight() - QPoint(iconSize + margin, 0), self.itemRect.topRight() + QPoint(0, iconSize + 2 * margin)) self.titleRect = QRect(self.iconRect.topRight() + QPoint(margin, 0), self.labelRect.bottomLeft() - QPoint(margin, margin)) self.bottomRect = QRect(QPoint(self.itemRect.x(), self.iconRect.bottom() + margin), QPoint(self.itemRect.right(), self.itemRect.bottom())) self.topRect = QRect(self.itemRect.topLeft(), self.bottomRect.topRight()) self.mainRect = self.bottomRect.adjusted(margin, margin, -margin, -margin) self.mainLineRect = QRect(self.mainRect.topLeft(), self.mainRect.topRight() + QPoint(0, iconSize)) self.mainTextRect = QRect(self.mainLineRect.bottomLeft() + QPoint(0, margin), self.mainRect.bottomRight()) if not item.data(Outline.summarySentance.value): self.mainTextRect.setTopLeft(self.mainLineRect.topLeft()) if item.data(Outline.label.value) in ["", "0"]: self.titleRect.setBottomRight(self.labelRect.bottomRight() - QPoint(self.margin, self.margin)) def paint(self, p, option, index): # QStyledItemDelegate.paint(self, p, option, index) if not index.isValid(): return item = index.internalPointer() self.updateRects(option, index) colors = outlineItemColors(item) style = qApp.style() def _rotate(angle): p.translate(self.mainRect.center()) p.rotate(angle) p.translate(-self.mainRect.center()) # Draw background cg = QPalette.ColorGroup(QPalette.Normal if option.state & QStyle.State_Enabled else QPalette.Disabled) if cg == QPalette.Normal and not option.state & QStyle.State_Active: cg = QPalette.Inactive # Selection if option.state & QStyle.State_Selected: p.save() p.setBrush(option.palette.brush(cg, QPalette.Highlight)) p.setPen(Qt.NoPen) p.drawRoundedRect(option.rect, 12, 12) p.restore() # Stack if item.isFolder() and item.childCount() > 0: p.save() p.setBrush(Qt.white) for i in reversed(range(3)): p.drawRoundedRect(self.itemRect.adjusted(2 * i, 2 * i, -2 * i, 2 * i), 10, 10) p.restore() # Background itemRect = self.itemRect p.save() if settings.viewSettings["Cork"]["Background"] != "Nothing": c = colors[settings.viewSettings["Cork"]["Background"]] col = mixColors(c, QColor(Qt.white), .2) p.setBrush(col) else: p.setBrush(Qt.white) pen = p.pen() pen.setWidth(2) p.setPen(pen) p.drawRoundedRect(itemRect, 10, 10) p.restore() # Title bar topRect = self.topRect p.save() if item.isFolder(): color = QColor(Qt.darkGreen) else: color = QColor(Qt.blue).lighter(175) p.setPen(Qt.NoPen) p.setBrush(color) p.setClipRegion(QRegion(topRect)) p.drawRoundedRect(itemRect, 10, 10) # p.drawRect(topRect) p.restore() # Label color if settings.viewSettings["Cork"]["Corner"] != "Nothing": p.save() color = colors[settings.viewSettings["Cork"]["Corner"]] p.setPen(Qt.NoPen) p.setBrush(color) p.setClipRegion(QRegion(self.labelRect)) p.drawRoundedRect(itemRect, 10, 10) # p.drawRect(topRect) p.restore() p.drawLine(self.labelRect.topLeft(), self.labelRect.bottomLeft()) # One line summary background lineSummary = item.data(Outline.summarySentance.value) fullSummary = item.data(Outline.summaryFull.value) if lineSummary or not fullSummary: m = self.margin r = self.mainLineRect.adjusted(-m, -m, m, m / 2) p.save() p.setPen(Qt.NoPen) p.setBrush(QColor("#EEE")) p.drawRect(r) p.restore() # Border p.save() p.setBrush(Qt.NoBrush) pen = p.pen() pen.setWidth(2) if settings.viewSettings["Cork"]["Border"] != "Nothing": col = colors[settings.viewSettings["Cork"]["Border"]] if col == Qt.transparent: col = Qt.black pen.setColor(col) p.setPen(pen) p.drawRoundedRect(itemRect, 10, 10) p.restore() # Draw the icon iconRect = self.iconRect mode = QIcon.Normal if not option.state & style.State_Enabled: mode = QIcon.Disabled elif option.state & style.State_Selected: mode = QIcon.Selected # index.data(Qt.DecorationRole).paint(p, iconRect, option.decorationAlignment, mode) icon = index.data(Qt.DecorationRole).pixmap(iconRect.size()) if settings.viewSettings["Cork"]["Icon"] != "Nothing": color = colors[settings.viewSettings["Cork"]["Icon"]] colorifyPixmap(icon, color) QIcon(icon).paint(p, iconRect, option.decorationAlignment, mode) # Draw title p.save() text = index.data() titleRect = self.titleRect if text: if settings.viewSettings["Cork"]["Text"] != "Nothing": col = colors[settings.viewSettings["Cork"]["Text"]] if col == Qt.transparent: col = Qt.black p.setPen(col) f = QFont(option.font) # f.setPointSize(f.pointSize() + 1) f.setBold(True) p.setFont(f) fm = QFontMetrics(f) elidedText = fm.elidedText(text, Qt.ElideRight, titleRect.width()) p.drawText(titleRect, Qt.AlignCenter, elidedText) p.restore() # Draw the line bottomRect = self.bottomRect p.save() # p.drawLine(itemRect.x(), iconRect.bottom() + margin, # itemRect.right(), iconRect.bottom() + margin) p.drawLine(bottomRect.topLeft(), bottomRect.topRight()) p.restore() # Lines if True: p.save() p.setPen(QColor("#EEE")) fm = QFontMetrics(option.font) h = fm.lineSpacing() l = self.mainTextRect.topLeft() + QPoint(0, h) while self.mainTextRect.contains(l): p.drawLine(l, QPoint(self.mainTextRect.right(), l.y())) l.setY(l.y() + h) p.restore() # Draw status mainRect = self.mainRect status = item.data(Outline.status.value) if status: it = mainWindow().mdlStatus.item(int(status), 0) if it != None: p.save() p.setClipRegion(QRegion(mainRect)) f = p.font() f.setPointSize(f.pointSize() + 12) f.setBold(True) p.setFont(f) p.setPen(QColor(Qt.red).lighter(175)) _rotate(-35) p.drawText(mainRect, Qt.AlignCenter, it.text()) p.restore() # Draw Summary # One line if lineSummary: p.save() f = QFont(option.font) f.setItalic(True) p.setFont(f) fm = QFontMetrics(f) elidedText = fm.elidedText(lineSummary, Qt.ElideRight, self.mainLineRect.width()) p.drawText(self.mainLineRect, Qt.AlignCenter, elidedText) p.restore() # Full summary if fullSummary: p.setFont(option.font) p.drawText(self.mainTextRect, Qt.TextWordWrap, fullSummary)
class corkDelegate(QStyledItemDelegate): def __init__(self, parent=None): QStyledItemDelegate.__init__(self, parent) self.factor = settings.corkSizeFactor / 100. self.lastPos = None self.editing = None self.margin = 5 self.bgColors = {} def newStyle(self): return settings.corkStyle == "new" def setCorkSizeFactor(self, v): self.factor = v / 100. def sizeHint(self, option, index): if self.newStyle(): defaultSize = QSize(300, 210) else: defaultSize = QSize(300, 200) return defaultSize * self.factor def editorEvent(self, event, model, option, index): # We catch the mouse position in the widget to know which part to edit if type(event) == QMouseEvent: self.lastPos = event.pos() # - option.rect.topLeft() return QStyledItemDelegate.editorEvent(self, event, model, option, index) def createEditor(self, parent, option, index): self.updateRects(option, index) bgColor = self.bgColors.get(index, "white") if self.mainLineRect.contains(self.lastPos): # One line summary self.editing = Outline.summarySentence edt = QLineEdit(parent) edt.setFocusPolicy(Qt.StrongFocus) edt.setFrame(False) f = QFont(option.font) if self.newStyle(): f.setBold(True) else: f.setItalic(True) edt.setAlignment(Qt.AlignCenter) edt.setPlaceholderText(self.tr("One line summary")) edt.setFont(f) edt.setStyleSheet("background: {}; color: black;".format(bgColor)) return edt elif self.titleRect.contains(self.lastPos): # Title self.editing = Outline.title edt = QLineEdit(parent) edt.setFocusPolicy(Qt.StrongFocus) edt.setFrame(False) f = QFont(option.font) if self.newStyle(): f.setPointSize(f.pointSize() + 4) else: edt.setAlignment(Qt.AlignCenter) f.setBold(True) edt.setFont(f) edt.setStyleSheet("background: {}; color: black;".format(bgColor)) # edt.setGeometry(self.titleRect) return edt else: # self.mainTextRect.contains(self.lastPos): # Summary self.editing = Outline.summaryFull edt = QPlainTextEdit(parent) edt.setFocusPolicy(Qt.StrongFocus) edt.setFrameShape(QFrame.NoFrame) try: # QPlainTextEdit.setPlaceholderText was introduced in Qt 5.3 edt.setPlaceholderText(self.tr("Full summary")) except AttributeError: pass edt.setStyleSheet("background: {}; color: black;".format(bgColor)) return edt def updateEditorGeometry(self, editor, option, index): if self.editing == Outline.summarySentence: # One line summary editor.setGeometry(self.mainLineRect) elif self.editing == Outline.title: # Title editor.setGeometry(self.titleRect) elif self.editing == Outline.summaryFull: # Summary editor.setGeometry(self.mainTextRect) def setEditorData(self, editor, index): item = index.internalPointer() if self.editing == Outline.summarySentence: # One line summary editor.setText(item.data(Outline.summarySentence)) elif self.editing == Outline.title: # Title editor.setText(index.data()) elif self.editing == Outline.summaryFull: # Summary editor.setPlainText(item.data(Outline.summaryFull)) def setModelData(self, editor, model, index): if self.editing == Outline.summarySentence: # One line summary model.setData(index.sibling(index.row(), Outline.summarySentence), editor.text()) elif self.editing == Outline.title: # Title model.setData(index, editor.text(), Outline.title) elif self.editing == Outline.summaryFull: # Summary model.setData(index.sibling(index.row(), Outline.summaryFull), editor.toPlainText()) def updateRects(self, option, index): if self.newStyle(): self.updateRects_v2(option, index) else: self.updateRects_v1(option, index) def updateRects_v2(self, option, index): margin = self.margin * 2 iconSize = max(24 * self.factor, 18) item = index.internalPointer() fm = QFontMetrics(option.font) h = fm.lineSpacing() self.itemRect = option.rect.adjusted(margin, margin, -margin, -margin) top = 15 * self.factor self.topRect = QRect(self.itemRect) self.topRect.setHeight(top) self.cardRect = QRect(self.itemRect.topLeft() + QPoint(0, top), self.itemRect.bottomRight()) self.iconRect = QRect(self.cardRect.topLeft() + QPoint(margin, margin), QSize(iconSize, iconSize)) self.labelRect = QRect(self.cardRect.topRight() - QPoint(margin + self.factor * 18, 1), self.cardRect.topRight() + QPoint(- margin - self.factor * 4, self.factor * 24)) self.titleRect = QRect(self.iconRect.topRight() + QPoint(margin, 0), self.labelRect.bottomLeft() - QPoint(margin, margin)) self.titleRect.setBottom(self.iconRect.bottom()) self.mainRect = QRect(self.iconRect.bottomLeft() + QPoint(0, margin), self.cardRect.bottomRight() - QPoint(margin, 2*margin)) self.mainRect.setLeft(self.titleRect.left()) self.mainLineRect = QRect(self.mainRect.topLeft(), self.mainRect.topRight() + QPoint(0, h)) self.mainTextRect = QRect(self.mainLineRect.bottomLeft() + QPoint(0, margin), self.mainRect.bottomRight()) if not item.data(Outline.summarySentence): self.mainTextRect.setTopLeft(self.mainLineRect.topLeft()) def updateRects_v1(self, option, index): margin = self.margin iconSize = max(16 * self.factor, 12) item = index.internalPointer() self.itemRect = option.rect.adjusted(margin, margin, -margin, -margin) self.iconRect = QRect(self.itemRect.topLeft() + QPoint(margin, margin), QSize(iconSize, iconSize)) self.labelRect = QRect(self.itemRect.topRight() - QPoint(iconSize + margin, 0), self.itemRect.topRight() + QPoint(0, iconSize + 2 * margin)) self.titleRect = QRect(self.iconRect.topRight() + QPoint(margin, 0), self.labelRect.bottomLeft() - QPoint(margin, margin)) self.bottomRect = QRect(QPoint(self.itemRect.x(), self.iconRect.bottom() + margin), QPoint(self.itemRect.right(), self.itemRect.bottom())) self.topRect = QRect(self.itemRect.topLeft(), self.bottomRect.topRight()) self.mainRect = self.bottomRect.adjusted(margin, margin, -margin, -margin) self.mainLineRect = QRect(self.mainRect.topLeft(), self.mainRect.topRight() + QPoint(0, iconSize)) self.mainTextRect = QRect(self.mainLineRect.bottomLeft() + QPoint(0, margin), self.mainRect.bottomRight()) if not item.data(Outline.summarySentence): self.mainTextRect.setTopLeft(self.mainLineRect.topLeft()) if item.data(Outline.label) in ["", "0", 0]: self.titleRect.setBottomRight(self.labelRect.bottomRight() - QPoint(self.margin, self.margin)) def paint(self, p, option, index): if self.newStyle(): self.paint_v2(p, option, index) else: self.paint_v1(p, option, index) def paint_v2(self, p, option, index): # QStyledItemDelegate.paint(self, p, option, index) if not index.isValid(): return item = index.internalPointer() self.updateRects(option, index) colors = outlineItemColors(item) style = qApp.style() def _rotate(angle, rect=self.mainRect): p.translate(rect.center()) p.rotate(angle) p.translate(-rect.center()) def drawRect(r): p.save() p.setBrush(Qt.gray) p.drawRect(r) p.restore() # Draw background cg = QPalette.ColorGroup(QPalette.Normal if option.state & QStyle.State_Enabled else QPalette.Disabled) if cg == QPalette.Normal and not option.state & QStyle.State_Active: cg = QPalette.Inactive # Selection if option.state & QStyle.State_Selected: p.save() p.setBrush(option.palette.brush(cg, QPalette.Highlight)) p.setPen(Qt.NoPen) #p.drawRoundedRect(option.rect, 12, 12) p.drawRect(option.rect) p.restore() # Background p.save() if settings.viewSettings["Cork"]["Background"] != "Nothing": c = colors[settings.viewSettings["Cork"]["Background"]] if c == QColor(Qt.transparent): c = QColor(Qt.white) col = mixColors(c, QColor(Qt.white), .2) backgroundColor = col p.setBrush(col) else: p.setBrush(Qt.white) backgroundColor = QColor(Qt.white) # Cache background color self.bgColors[index] = backgroundColor.name() p.setPen(Qt.NoPen) p.drawRect(self.cardRect) if item.isFolder(): itemPoly = QPolygonF([ self.topRect.topLeft(), self.topRect.topLeft() + QPoint(self.topRect.width() * .35, 0), self.cardRect.topLeft() + QPoint(self.topRect.width() * .45, 0), self.cardRect.topRight(), self.cardRect.bottomRight(), self.cardRect.bottomLeft() ]) p.drawPolygon(itemPoly) p.restore() # Label color if settings.viewSettings["Cork"]["Corner"] != "Nothing": p.save() color = colors[settings.viewSettings["Cork"]["Corner"]] p.setPen(Qt.NoPen) p.setBrush(color) p.drawRect(self.labelRect) w = self.labelRect.width() poly = QPolygonF([ self.labelRect.bottomLeft() + QPointF(0, 1), self.labelRect.bottomLeft() + QPointF(0, w / 2), self.labelRect.bottomLeft() + QPointF(w / 2, 1), self.labelRect.bottomRight() + QPointF(1, w / 2), self.labelRect.bottomRight() + QPointF(1, 1), ]) p.drawPolygon(poly) p.restore() if settings.viewSettings["Cork"]["Corner"] == "Nothing" or \ color == Qt.transparent: # No corner, so title can be full width self.titleRect.setRight(self.mainRect.right()) # Draw the icon iconRect = self.iconRect mode = QIcon.Normal if not option.state & style.State_Enabled: mode = QIcon.Disabled elif option.state & style.State_Selected: mode = QIcon.Selected # index.data(Qt.DecorationRole).paint(p, iconRect, option.decorationAlignment, mode) icon = index.data(Qt.DecorationRole).pixmap(iconRect.size()) if settings.viewSettings["Cork"]["Icon"] != "Nothing": color = colors[settings.viewSettings["Cork"]["Icon"]] colorifyPixmap(icon, color) QIcon(icon).paint(p, iconRect, option.decorationAlignment, mode) # Draw title p.save() text = index.data() if text: p.setPen(Qt.black) textColor = QColor(Qt.black) if settings.viewSettings["Cork"]["Text"] != "Nothing": col = colors[settings.viewSettings["Cork"]["Text"]] if col == Qt.transparent: col = Qt.black # If title setting is compile, we have to hack the color # Or we won't see anything in some themes if settings.viewSettings["Cork"]["Text"] == "Compile": if item.compile() in [0, "0"]: col = mixColors(QColor(Qt.black), backgroundColor) else: col = Qt.black textColor = col p.setPen(col) f = QFont(option.font) f.setPointSize(f.pointSize() + 4) f.setBold(True) p.setFont(f) fm = QFontMetrics(f) elidedText = fm.elidedText(text, Qt.ElideRight, self.titleRect.width()) p.drawText(self.titleRect, Qt.AlignLeft | Qt.AlignVCenter, elidedText) p.restore() # One line summary background lineSummary = item.data(Outline.summarySentence) fullSummary = item.data(Outline.summaryFull) # Border if settings.viewSettings["Cork"]["Border"] != "Nothing": p.save() p.setBrush(Qt.NoBrush) pen = p.pen() pen.setWidth(2) col = colors[settings.viewSettings["Cork"]["Border"]] pen.setColor(col) p.setPen(pen) if item.isFolder(): p.drawPolygon(itemPoly) else: p.drawRect(self.cardRect) p.restore() # Draw status status = item.data(Outline.status) if status: it = mainWindow().mdlStatus.item(int(status), 0) if it != None: p.save() p.setClipRegion(QRegion(self.cardRect)) f = p.font() f.setPointSize(f.pointSize() + 12) f.setBold(True) p.setFont(f) p.setPen(QColor(Qt.red).lighter(170)) _rotate(-35, rect=self.cardRect) p.drawText(self.cardRect, Qt.AlignCenter, it.text()) p.restore() # Draw Summary # One line if lineSummary: p.save() f = QFont(option.font) f.setBold(True) p.setFont(f) p.setPen(textColor) fm = QFontMetrics(f) elidedText = fm.elidedText(lineSummary, Qt.ElideRight, self.mainLineRect.width()) p.drawText(self.mainLineRect, Qt.AlignLeft | Qt.AlignVCenter, elidedText) p.restore() # Full summary if fullSummary: p.save() p.setFont(option.font) p.setPen(textColor) p.drawText(self.mainTextRect, Qt.TextWordWrap, fullSummary) p.restore() def paint_v1(self, p, option, index): # QStyledItemDelegate.paint(self, p, option, index) if not index.isValid(): return item = index.internalPointer() self.updateRects(option, index) colors = outlineItemColors(item) style = qApp.style() def _rotate(angle): p.translate(self.mainRect.center()) p.rotate(angle) p.translate(-self.mainRect.center()) # Draw background cg = QPalette.ColorGroup(QPalette.Normal if option.state & QStyle.State_Enabled else QPalette.Disabled) if cg == QPalette.Normal and not option.state & QStyle.State_Active: cg = QPalette.Inactive # Selection if option.state & QStyle.State_Selected: p.save() p.setBrush(option.palette.brush(cg, QPalette.Highlight)) p.setPen(Qt.NoPen) p.drawRoundedRect(option.rect, 12, 12) p.restore() # Stack if item.isFolder() and item.childCount() > 0: p.save() p.setBrush(Qt.white) for i in reversed(range(3)): p.drawRoundedRect(self.itemRect.adjusted(2 * i, 2 * i, -2 * i, 2 * i), 10, 10) p.restore() # Background itemRect = self.itemRect p.save() if settings.viewSettings["Cork"]["Background"] != "Nothing": c = colors[settings.viewSettings["Cork"]["Background"]] col = mixColors(c, QColor(Qt.white), .2) p.setBrush(col) else: p.setBrush(Qt.white) pen = p.pen() pen.setWidth(2) p.setPen(pen) p.drawRoundedRect(itemRect, 10, 10) p.restore() # Title bar topRect = self.topRect p.save() if item.isFolder(): color = QColor(Qt.darkGreen) else: color = QColor(Qt.blue).lighter(175) p.setPen(Qt.NoPen) p.setBrush(color) p.setClipRegion(QRegion(topRect)) p.drawRoundedRect(itemRect, 10, 10) # p.drawRect(topRect) p.restore() # Label color if settings.viewSettings["Cork"]["Corner"] != "Nothing": p.save() color = colors[settings.viewSettings["Cork"]["Corner"]] p.setPen(Qt.NoPen) p.setBrush(color) p.setClipRegion(QRegion(self.labelRect)) p.drawRoundedRect(itemRect, 10, 10) # p.drawRect(topRect) p.restore() if color != Qt.transparent: p.drawLine(self.labelRect.topLeft(), self.labelRect.bottomLeft()) # One line summary background lineSummary = item.data(Outline.summarySentence) fullSummary = item.data(Outline.summaryFull) if lineSummary or not fullSummary: m = self.margin r = self.mainLineRect.adjusted(-m, -m, m, m / 2) p.save() p.setPen(Qt.NoPen) p.setBrush(QColor("#EEE")) p.drawRect(r) p.restore() # Border p.save() p.setBrush(Qt.NoBrush) pen = p.pen() pen.setWidth(2) if settings.viewSettings["Cork"]["Border"] != "Nothing": col = colors[settings.viewSettings["Cork"]["Border"]] if col == Qt.transparent: col = Qt.black pen.setColor(col) p.setPen(pen) p.drawRoundedRect(itemRect, 10, 10) p.restore() # Draw the icon iconRect = self.iconRect mode = QIcon.Normal if not option.state & style.State_Enabled: mode = QIcon.Disabled elif option.state & style.State_Selected: mode = QIcon.Selected # index.data(Qt.DecorationRole).paint(p, iconRect, option.decorationAlignment, mode) icon = index.data(Qt.DecorationRole).pixmap(iconRect.size()) if settings.viewSettings["Cork"]["Icon"] != "Nothing": color = colors[settings.viewSettings["Cork"]["Icon"]] colorifyPixmap(icon, color) QIcon(icon).paint(p, iconRect, option.decorationAlignment, mode) # Draw title p.save() text = index.data() titleRect = self.titleRect if text: if settings.viewSettings["Cork"]["Text"] != "Nothing": col = colors[settings.viewSettings["Cork"]["Text"]] if col == Qt.transparent: col = Qt.black p.setPen(col) f = QFont(option.font) # f.setPointSize(f.pointSize() + 1) f.setBold(True) p.setFont(f) fm = QFontMetrics(f) elidedText = fm.elidedText(text, Qt.ElideRight, titleRect.width()) p.drawText(titleRect, Qt.AlignCenter, elidedText) p.restore() # Draw the line bottomRect = self.bottomRect p.save() # p.drawLine(itemRect.x(), iconRect.bottom() + margin, # itemRect.right(), iconRect.bottom() + margin) p.drawLine(bottomRect.topLeft(), bottomRect.topRight()) p.restore() # Lines if True: p.save() p.setPen(QColor("#EEE")) fm = QFontMetrics(option.font) h = fm.lineSpacing() l = self.mainTextRect.topLeft() + QPoint(0, h) while self.mainTextRect.contains(l): p.drawLine(l, QPoint(self.mainTextRect.right(), l.y())) l.setY(l.y() + h) p.restore() # Draw status mainRect = self.mainRect status = item.data(Outline.status) if status: it = mainWindow().mdlStatus.item(int(status), 0) if it != None: p.save() p.setClipRegion(QRegion(mainRect)) f = p.font() f.setPointSize(f.pointSize() + 12) f.setBold(True) p.setFont(f) p.setPen(QColor(Qt.red).lighter(175)) _rotate(-35) p.drawText(mainRect, Qt.AlignCenter, it.text()) p.restore() # Draw Summary # One line if lineSummary: p.save() f = QFont(option.font) f.setItalic(True) p.setFont(f) fm = QFontMetrics(f) elidedText = fm.elidedText(lineSummary, Qt.ElideRight, self.mainLineRect.width()) p.drawText(self.mainLineRect, Qt.AlignCenter, elidedText) p.restore() # Full summary if fullSummary: p.setFont(option.font) p.drawText(self.mainTextRect, Qt.TextWordWrap, fullSummary)