def setGeometry(self, rect: QRect): super().setGeometry(rect) if not self.items: return contents = self.contentsRect() if contents.height() > 0: c_aratio = contents.width() / contents.height() else: c_aratio = 1 s_aratio = self.aspect_ratio item_rect = QRect( QPoint(0, 0), QSize( contents.width() if c_aratio < s_aratio else contents.height() * s_aratio, contents.height() if c_aratio > s_aratio else contents.width() / s_aratio)) content_margins = self.contentsMargins() free_space = contents.size() - item_rect.size() for item in self.items: if free_space.width() > 0 and not item.alignment() & Qt.AlignLeft: if item.alignment() & Qt.AlignRight: item_rect.moveRight(contents.width() + content_margins.right()) else: item_rect.moveLeft(content_margins.left() + (free_space.width() / 2)) else: item_rect.moveLeft(content_margins.left()) if free_space.height() > 0 and not item.alignment() & Qt.AlignTop: if item.alignment() & Qt.AlignBottom: item_rect.moveBottom(contents.height() + content_margins.bottom()) else: item_rect.moveTop(content_margins.top() + (free_space.height() / 2)) else: item_rect.moveTop(content_margins.top()) item.widget().setGeometry(item_rect)
def drawComplexControl(self, element, opt, painter, widget): if not self.__panel_widget(widget): QProxyStyle.drawComplexControl(self, element, opt, painter, widget) return if element == QStyle.CC_ComboBox: empty = False if not opt.currentText and opt.currentIcon.isNull(): empty = True tool_btn = opt if empty: tool_btn.state &= ~(STATE_ENABLED | STATE_SUNKEN) self.drawPrimitive(QStyle.PE_PanelButtonTool, tool_btn, painter, widget) # Draw border if widget.property("border"): # painter.setPen(opt.palette.light().color().lighter(150)) painter.setPen(_COLORS["MenuBarBorderColor"]) painter.drawLine(opt.rect.topRight() + QPoint(0, 6), opt.rect.bottomRight() - QPoint(0, 6)) if widget.property("border_bottom"): painter.setPen(_COLORS['Border']) painter.drawLine(opt.rect.bottomLeft(), opt.rect.bottomRight()) arrow_rect = QRect((opt.rect.left() + opt.rect.right()) / 2 + 6, opt.rect.center().y(), 9, 9) arrow_rect.moveRight(opt.rect.width() - 10) # FIXME: arrow_opt = QStyleOptionComboBox() arrow_opt.state = opt.state arrow_opt.rect = arrow_rect if empty: arrow_opt.state &= ~(STATE_ENABLED | STATE_SUNKEN) if self.styleHint(QStyle.SH_ComboBox_Popup, opt, widget): arrow_opt.rect.translate(0, -3) arrow_opt.palette.setColor(QPalette.ButtonText, _COLORS['IconBaseColor']) QCommonStyle.drawPrimitive(self, QStyle.PE_IndicatorArrowDown, arrow_opt, painter, widget) # elif element == QStyle.CC_ScrollBar: # pass elif element == QStyle.CC_ToolButton: # reverse = opt.direction == Qt.RightToLeft button = self.subControlRect(element, opt, QStyle.SC_ToolButton, widget) flags = opt.state if flags & QStyle.State_AutoRaise: if not flags & STATE_MOUSEOVER: flags &= ~QStyle.State_Raised tool = opt tool.palette = self.panel_palette(opt.palette) if opt.subControls & QStyle.SC_ToolButton: tool.rect = button tool.state = flags self.drawPrimitive(QStyle.PE_PanelButtonTool, tool, painter, widget) # Draw border if widget.property("border"): # painter.setPen(_COLORS["MenuBarBorderColor"]) # painter.drawLine(opt.rect.bottomLeft(), opt.rect.bottomRight()) pass label = opt label.palette.setColor(QPalette.ButtonText, label.palette.buttonText().color()) fw = self.pixelMetric(QStyle.PM_DefaultFrameWidth, opt, widget) label.rect = opt.rect.adjusted(fw, fw, -fw, -fw) self.drawControl(QStyle.CE_ToolButtonLabel, label, painter, widget) else: QProxyStyle.drawComplexControl(self, element, opt, painter, widget)
def drawMagnifier(self): # First, calculate the magnifier position due to the mouse position watchAreaWidth = 16 watchAreaHeight = 16 watchAreaPixmap = QPixmap() cursor_pos = self.mousePoint watchArea = QRect( QPoint(cursor_pos.x() - watchAreaWidth / 2, cursor_pos.y() - watchAreaHeight / 2), QPoint(cursor_pos.x() + watchAreaWidth / 2, cursor_pos.y() + watchAreaHeight / 2)) if watchArea.left() < 0: watchArea.moveLeft(0) watchArea.moveRight(watchAreaWidth) if self.mousePoint.x() + watchAreaWidth / 2 >= self.screenPixel.width( ): watchArea.moveRight(self.screenPixel.width() - 1) watchArea.moveLeft(watchArea.right() - watchAreaWidth) if self.mousePoint.y() - watchAreaHeight / 2 < 0: watchArea.moveTop(0) watchArea.moveBottom(watchAreaHeight) if self.mousePoint.y( ) + watchAreaHeight / 2 >= self.screenPixel.height(): watchArea.moveBottom(self.screenPixel.height() - 1) watchArea.moveTop(watchArea.bottom() - watchAreaHeight) # tricks to solve the hidpi impact on QCursor.pos() watchArea.setTopLeft( QPoint(watchArea.topLeft().x() * self.scale, watchArea.topLeft().y() * self.scale)) watchArea.setBottomRight( QPoint(watchArea.bottomRight().x() * self.scale, watchArea.bottomRight().y() * self.scale)) watchAreaPixmap = self.screenPixel.copy(watchArea) # second, calculate the magnifier area magnifierAreaWidth = watchAreaWidth * 10 magnifierAreaHeight = watchAreaHeight * 10 fontAreaHeight = 40 cursorSize = 24 magnifierArea = QRectF( QPoint(QCursor.pos().x() + cursorSize, QCursor.pos().y() + cursorSize), QPoint(QCursor.pos().x() + cursorSize + magnifierAreaWidth, QCursor.pos().y() + cursorSize + magnifierAreaHeight)) if magnifierArea.right() >= self.screenPixel.width(): magnifierArea.moveLeft(QCursor.pos().x() - magnifierAreaWidth - cursorSize / 2) if magnifierArea.bottom() + fontAreaHeight >= self.screenPixel.height( ): magnifierArea.moveTop(QCursor.pos().y() - magnifierAreaHeight - cursorSize / 2 - fontAreaHeight) # third, draw the watch area to magnifier area watchAreaScaled = watchAreaPixmap.scaled( QSize(magnifierAreaWidth * self.scale, magnifierAreaHeight * self.scale)) magnifierPixmap = self.graphicsScene.addPixmap(watchAreaScaled) magnifierPixmap.setOffset(magnifierArea.topLeft()) # then draw lines and text self.graphicsScene.addRect(QRectF(magnifierArea), QPen(QColor(255, 255, 255), 2)) self.graphicsScene.addLine( QLineF(QPointF(magnifierArea.center().x(), magnifierArea.top()), QPointF(magnifierArea.center().x(), magnifierArea.bottom())), QPen(QColor(0, 255, 255), 2)) self.graphicsScene.addLine( QLineF(QPointF(magnifierArea.left(), magnifierArea.center().y()), QPointF(magnifierArea.right(), magnifierArea.center().y())), QPen(QColor(0, 255, 255), 2)) # get the rgb of mouse point pointRgb = QColor(self.screenPixel.toImage().pixel(self.mousePoint)) # draw information self.graphicsScene.addRect( QRectF( magnifierArea.bottomLeft(), magnifierArea.bottomRight() + QPoint(0, fontAreaHeight + 30)), Qt.black, QBrush(Qt.black)) rgbInfo = self.graphicsScene.addSimpleText( ' Rgb: ({0}, {1}, {2})'.format(pointRgb.red(), pointRgb.green(), pointRgb.blue())) rgbInfo.setPos(magnifierArea.bottomLeft() + QPoint(0, 5)) rgbInfo.setPen(QPen(QColor(255, 255, 255), 2)) rect = self.selectedArea.normalized() sizeInfo = self.graphicsScene.addSimpleText(' Size: {0} x {1}'.format( rect.width() * self.scale, rect.height() * self.scale)) sizeInfo.setPos(magnifierArea.bottomLeft() + QPoint(0, 15) + QPoint(0, fontAreaHeight / 2)) sizeInfo.setPen(QPen(QColor(255, 255, 255), 2))
class Slider(QPushButton): def __init__(self, parent, value=False): super().__init__(parent) self.setMinimumWidth(52) self.setMinimumHeight(24) self.background_on = QColor(0, 120, 212) self.background_off = QColor(255, 255, 255) self.radius = 10 self.click_width = 24 self.click_rect = QRect(-self.click_width, -self.radius, 2 * self.click_width, 2 * self.radius) self.dot_rect = QRect(-self.click_width, -self.radius, 20, 20) self.background = self.background_off self.pen = QPen(QColor(194, 194, 194)) self.pen.setWidth(2) self.setCheckable(True) self.setChecked(value) def refresh(self): pass def mousePressEvent(self, event): self.setChecked(not self.isChecked()) def enterEvent(self, event): self.setCursor(Qt.PointingHandCursor) def leaveEvent(self, event): self.setCursor(Qt.ArrowCursor) def setChecked(self, value): super().setChecked(value) if self.isChecked(): self.background = self.background_on self.pen.setColor(self.background) self.dot_rect.moveRight(self.click_width) else: self.background = self.background_off self.pen.setColor(QColor(194, 194, 194)) self.dot_rect.moveLeft(-self.click_width) self.update() def paintEvent(self, event): painter = QPainter(self) painter.setRenderHint(QPainter.HighQualityAntialiasing) # painter.drawRect(self.rect()) painter.translate(self.rect().center()) painter.setBrush(QBrush(self.background)) painter.setPen(self.pen) painter.drawRoundedRect(self.click_rect, self.radius, self.radius) painter.setBrush(QBrush(QColor(0, 0, 0))) painter.drawRoundedRect(self.dot_rect, 10, 10) painter.end()