def paintEvent(self, pe): painter = QPainter(self) painter.save() gradient = QLinearGradient() gradient.setStart(self._grad_start) gradient.setFinalStop(self._grad_end) gradient.setColorAt(0, QColor(230, 230, 230)) gradient.setColorAt(1, QColor(247, 247, 247)) brush = QBrush(gradient) painter.setBrush(brush) pen = QPen(Qt.black) pen.setWidth(1) painter.setPen(pen) painter.drawPath(self._painter_path) painter.restore() font = QFont() font.setFamily("Tahoma") font.setPixelSize(11) font.setBold(True) pen = QPen(Qt.darkGray) painter.setPen(pen) painter.setFont(font) self_rect = QRect(self.rect()) self_rect.moveTo(self._hor_margin, self._ver_margin // 2) painter.drawText(self_rect, Qt.AlignLeft, self._text)
def paint(self, painter, option, index): rect = option.rect movie = index.data(Qt.UserRole) painter.setOpacity(0.7) if option.state & QStyle.State_Selected: painter.drawRect(rect) # draw poster background painter.setPen(self.outline) painter.setBrush(self.backgoundBrush) painter.drawRect(rect) # draw poster pixmap = QPixmap(movie.poster).scaled(rect.width() - 25, rect.height() - 50, Qt.KeepAspectRatio, Qt.SmoothTransformation) posterRect = QRect(rect.x() + 15, rect.y() + 15, pixmap.width(), pixmap.height()) painter.drawPixmap(posterRect, pixmap) # draw movie title titleRect = QRect(rect.x(), rect.bottom() - 30, rect.width(), rect.height()) releaseText = "({})".format( movie.releaseDate.split("-")[0]) if movie.releaseDate else "" painter.drawText(titleRect, Qt.AlignHCenter, u"{0} {1}".format(movie.name, releaseText))
def testNoIntersectBounding(self): '''QRect | QRect for non-intersecting QRects Non-intersecting QRects return a greater QRect for operator |''' rect1 = QRect(10, 10, 5, 5) rect2 = QRect(20, 20, 5, 5) rect3 = rect1 | rect2 self.assertEqual(rect3, QRect(10, 10, 15, 15))
def testNoIntersect(self): '''QRect & QRect for non-intersecting QRects Non-intersecting QRects return a 'null' QRect for operator &''' rect1 = QRect(10, 10, 5, 5) rect2 = QRect(20, 20, 5, 5) rect3 = rect1 & rect2 self.assertEqual(rect3, QRect())
def testNullRectIntersectBounding(self): #QRect | QRect for null rects rect1 = QRect() rect2 = QRect() rect3 = rect1 & rect2 self.assertEqual(rect3, rect1) self.assertEqual(rect3, rect2)
def _calculate_bounds(self): width = self.width() height = self.height() # Hue palette self._hue_rect = QRect(width - self._hue_width, 0, self._hue_width, height) # Shades palette self._shades_rect = QRect(0, 0, width - (self._hue_width + self._gap), height)
def _draw_selected_items_in_series(self, painter): fm = painter.fontMetrics() pen = QPen() pen.setWidth(1) pen.setColor(Qt.GlobalColor.white) painter.setPen(pen) # We assume all series have the very same number of values # and all values on the same index are drawn on the same X # coordinate ndx_serie = self.best_serie_intra_ndx aesthetic_shift = 5 if ndx_serie is not None: to_draw = [] for i in range(len(self.data)): x, y = self._item_coordinates_lines(i, ndx_serie) #mainlog.debug("{} {}".format(ndx_serie,i)) v = self.data[i][ndx_serie] text = str(int(v)) to_draw.append( (self.y_base - y, text) ) last_y = 100000 for y, text in sorted( to_draw, key=lambda z : z[0], reverse=True): r = QRect(x + aesthetic_shift,0,1000,1000) bb = painter.boundingRect(r,Qt.AlignLeft,text) if bb.right() > self.width(): x = x - bb.width() - 2*aesthetic_shift# left align if y + bb.height() > last_y: y = last_y - bb.height() fill_color = QColor(16, 16, 48) fill_color.setAlpha(196) brush = QBrush(fill_color) margin = 2 r = QRect(x + aesthetic_shift - margin, y - aesthetic_shift - bb.height() - margin, bb.width() + 2*margin, bb.height() + 2*margin) painter.fillRect(r, brush) painter.drawText(x + aesthetic_shift, y - aesthetic_shift, text) last_y = y x, y = self._item_coordinates_lines(0, ndx_serie) qp = QPainterPath() qp.moveTo(x, self.y_base) qp.lineTo(x, self.y_base - self.total_height) painter.drawPath(qp)
def testConstructorQPoint(self): topLeft = QPoint(3, 0) bottomRight = QPoint(0, 3) rect1 = QRect(topLeft, bottomRight) rect2 = QRect(topLeft, bottomRight) self.assertEqual(rect1, rect2)
def _draw_legend2(self, painter, labels): text_pen = QPen() text_pen.setCapStyle(Qt.RoundCap) text_pen.setColor(QColor(200, 200, 200)) # alpha=255=fully opaque text_pen.setWidth(1) highlighted_text_pen = QPen() highlighted_text_pen.setColor(QColor(255, 255, 255)) # alpha=255=fully opaque highlighted_text_pen.setWidth(1) line_pen = QPen() line_pen.setCapStyle(Qt.RoundCap) line_pen.setColor(QColor(200, 200, 200)) # alpha=255=fully opaque line_pen.setWidth(2) row = col = 0 self.legend_labels_bounding_boxes = [] for data_ndx, label in sorted( zip(range(len(labels)),labels), key=lambda a:a[1]): if label: # One can hide a series' legend by using a blank label x = self.margin + col * self.max_legend_label_width + 3 y = self.legend_y_start + row * self.text_height # Draw coloured line line_pen.setColor(self.graph_colors[data_ndx % len(self.graph_colors)]) # alpha=255=fully opaque painter.setPen(line_pen) if data_ndx == self.ndx_best_serie: r = QRect(x-3, y-self.text_height+3, self.max_legend_label_width, self.text_height) painter.drawRect(r) painter.setPen(highlighted_text_pen) else: painter.drawLine(x,y+3,x+self.max_legend_label_width - 6,y + 3) painter.setPen(text_pen) painter.drawText(x,y, label) # Remember text bounding box r = QRect(x,y - self.text_height, self.max_legend_label_width, self.text_height) bb = painter.boundingRect(r,Qt.AlignLeft,label) # if label == 'TV': # painter.drawRect(r) self.legend_labels_bounding_boxes.append( (data_ndx,r) ) if not (col < self.legend_labels_per_line - 1): col = 0 row += 1 else: col += 1
def testEqual(self): '''QRect == QRect Note: operator == must be working as it's the main check for correctness''' rect1 = QRect() rect2 = QRect() self.assertEqual(rect1, rect2) rect1 = QRect(0, 4, 100, 300) rect2 = QRect(0, 4, 100, 300) self.assertEqual(rect1, rect2)
def scene_item_rects_updated(self, items): """The user moved or resized items in the scene """ debug_print('GraphicsItemView.item_rects_updated') for index, item in izip(self.indexes_of_items(items), items): # item.sceneBoundingRect() is the items rects in the correct # coordinates system debug_print('Row [{0}] updated'.format(index.row())) rect = item.sceneBoundingRect() # Cumbersome conversion to ints rect = QRect(rect.left(), rect.top(), rect.width(), rect.height()) self.model().setData(index, rect, RectRole)
def _setupPainterPath(self): painter_path = QPainterPath() painter_path.moveTo(0, 15) #left painter_path.lineTo(0, 0) #up painter_path.lineTo(self.width() - 1, 0) # right painter_path.lineTo(self.width() - 1, 15) # down painter_path.arcTo(QRect(self.width() - 6, 15, 5, 4), 0, -90) # control point1, cp2, destPoint painter_path.lineTo(5, 19) # left painter_path.arcTo(QRect(1, 15, 5, 4), 270, -90) #arc left up painter_path.closeSubpath() self._painter_path = painter_path
def animateWidget(self, widget, distance, direction): widget_anim = QPropertyAnimation(widget, "geometry") cur_geom = widget.geometry() next_geom = QRect(cur_geom) if direction == self.LEFT: next_geom.moveTo(widget.pos() - QPoint(distance, 0)) elif direction == self.RIGHT: next_geom.moveTo(widget.pos() + QPoint(distance, 0)) widget_anim.setDuration(self.ANIM_DURATION) widget_anim.setEasingCurve(self.EASING) widget_anim.setStartValue(cur_geom) widget_anim.setEndValue(next_geom) self._anim_grp.addAnimation(widget_anim)
def _setupAnimation(self): self._load_animation = QPropertyAnimation(self._label_movie, "geometry") # since the opacity is failing, make it run out of the area! anim_label_geom = self._label_movie.geometry() self._load_animation.setStartValue(anim_label_geom) target_anim_geom = QRect(anim_label_geom) target_anim_geom.moveTop(self.height()) # make the animation target a rectangle that's directly under it but shifted downwards outside of parent self._load_animation.setEndValue(target_anim_geom) self._load_animation.setEasingCurve(QEasingCurve.InBack) self._load_animation.setDuration(1000) self._load_animation.finished.connect(self.animation_finished) self._load_animation.finished.connect(self._hideAnimLabel)
def initializeComposition(self): """Main Dialog""" self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint) self.setFocusPolicy(Qt.StrongFocus) self.setFrameStyle(QFrame.StyledPanel | QFrame.Raised) #Font will appear in buttons self.setFont( QFont(self.options.getQuizFont(), self.options.getQuizFontSize())) desktop = QApplication.desktop().screenGeometry() self.setGeometry( QRect(desktop.width() - H_INDENT, desktop.height() - V_INDENT, D_WIDTH, D_HEIGHT)) self.setStyleSheet("QWidget { background-color: rgb(255, 255, 255); }") """Info dialog""" self.info.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint) self.info.setFrameStyle(QFrame.StyledPanel | QFrame.Raised) self.info.setGeometry( QRect(desktop.width() - H_INDENT - I_WIDTH - I_INDENT, desktop.height() - V_INDENT, I_WIDTH, I_HEIGHT)) self.info.setFixedSize(I_WIDTH, I_HEIGHT) self.info.setStyleSheet( "QWidget { background-color: rgb(255, 255, 255); }") """Verbose info dialog""" self.allInfo.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint) self.allInfo.setFrameStyle(QFrame.StyledPanel | QFrame.Raised) self.allInfo.setGeometry( QRect(desktop.width() - H_INDENT - I_WIDTH - I_INDENT, desktop.height() - V_INDENT, I_WIDTH, I_HEIGHT)) self.allInfo.setStyleSheet( "QWidget { background-color: rgb(255, 255, 255); }") """Session message""" self.status.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint) self.status.setFrameStyle(QFrame.StyledPanel | QFrame.Raised) self.status.setGeometry( QRect( desktop.width() - H_INDENT, desktop.height() - V_INDENT - S_HEIGHT - S_INDENT - S_CORRECTION, S_WIDTH, S_HEIGHT)) self.status.setStyleSheet( "QWidget { background-color: rgb(255, 255, 255); }") self.setMask(roundCorners(self.rect(), 5)) self.status.setMask(roundCorners(self.status.rect(), 5))
def set_shape(self, width, height): ''' ANSWER has round, disjoint sides - does not fit in a polygon ''' self.width, self.height = width, height point = width / 2.85 path = QPainterPath() left = QRect(0, 0, point, height) right = QRect(width - point, 0, point, height) path.arcMoveTo(left, 125) path.arcTo(left, 125, 110) path.arcMoveTo(right, -55) path.arcTo(right, -55, 110) path.moveTo(width, height) self.setPath(path) super(DecisionAnswer, self).set_shape(width, height)
def click(self, element, left, top, width, height): elementBox = QRect(left, top, width, height) parent = element.webFrame() while parent: elementBox = elementBox.translated(parent.geometry().topLeft()) parent = parent.parentFrame() viewport = QRect(QPoint(0, 0),self._view.viewportSize()) mousePos = elementBox.intersected(viewport).center() event = QMouseEvent(QEvent.MouseMove,mousePos, Qt.NoButton, Qt.NoButton, Qt.NoModifier) self._view.app.sendEvent(self._view, event) event = QMouseEvent(QEvent.MouseButtonPress,mousePos, Qt.LeftButton, Qt.LeftButton, Qt.NoModifier) self._view.app.sendEvent(self._view, event) event = QMouseEvent(QEvent.MouseButtonRelease,mousePos, Qt.LeftButton, Qt.LeftButton, Qt.NoModifier) self._view.app.sendEvent(self._view, event) href = element.attribute('href') if element.hasAttribute('href') else ''
def set_rect(self, new_rect): """Sets a new QRect in integer coordinates """ # Cumbersome conversion to ints current = self.sceneBoundingRect() current = QRect(current.left(), current.top(), current.width(), current.height()) if current != new_rect: msg = 'Update rect for [{0}] from [{1}] to [{2}]' debug_print(msg.format(self, current, new_rect)) self.prepareGeometryChange() # setrect() expects floating point rect self.setRect(QRectF(new_rect))
def getInfo(self): """TOWRITE""" # TODO: generate a temporary pattern from the scene data. # TODO: grab this information from the pattern self.stitchesTotal = 5 # TODO: embStitchList_count(pattern->stitchList, TOTAL) self.stitchesReal = 4 # TODO: embStitchList_count(pattern->stitchList, NORMAL) self.stitchesJump = 3 # TODO: embStitchList_count(pattern->stitchList, JUMP) self.stitchesTrim = 2 # TODO: embStitchList_count(pattern->stitchList, TRIM) self.colorTotal = 1 # TODO: embThreadList_count(pattern->threadList, TOTAL) self.colorChanges = 0 # TODO: embThreadList_count(pattern->threadList, CHANGES) self.boundingRect = QRect() #TODO/FIXME# self.boundingRect.setRect( 0, 0, 50, 100) # TODO: embPattern_calcBoundingBox(pattern)
def paint(self, painter, point): painter.save() size = QSize(self.width(), self.height()) painter.setBrush(self.bg_color) painter.drawRoundedRect(QRect(point, size), BLOCK_RADIUS, BLOCK_RADIUS) # Рисуем столбцы p = QPoint(point) + QPoint(0, BLOCK_RADIUS) for c in self.columns: p += QPoint(BLOCK_RADIUS, 0) c.paint(painter, p) p += QPoint(c.width(), 0) # Рисуем левые порты if len(self.left_pins): p = QPoint(point) p += QPoint(0, size.height() / (len(self.left_pins) + 1)) for lp in self.left_pins: lp.paint(painter, p) p += QPoint(0, size.height() / (len(self.left_pins) + 1)) # Рисуем правые порты if len(self.right_pins): p = QPoint(point) p += QPoint(size.width(), size.height() / (len(self.right_pins) + 1)) for rp in self.right_pins: rp.paint(painter, p) p += QPoint(0, size.height() / (len(self.right_pins) + 1)) painter.restore()
def saveAsPdf(self, fn, force=False): """ Save bar image as a eps file. Args: fn: Filename force: if True, overwrites an existing file. If false, raises a RuntimeError if file already exists. """ printer = QPrinter(QPrinter.HighResolution) printer.setOutputFormat(QPrinter.PdfFormat) printer.setOutputFileName(fn) printer.setFullPage(True) printer.setPageSize(QPrinter.Custom) printer.setPaperSize(QSizeF(*self.size), QPrinter.Millimeter) printer.setPageMargins(0, 0, 0, 0, QPrinter.Millimeter) painter = QPainter(printer) painter.setRenderHint(QPainter.Antialiasing) painter.setBrush(Qt.white) painter.setPen(Qt.white) painter.drawRect(QRect(0, 0, *self.size)) targetrect = QRectF(0, 0, printer.width(), printer.height()) sourcerect = QRectF(0, 0, *self.size) self.render(painter, targetrect, sourcerect) painter.end() return True
def saveAsBitmap(self, fn): """ Save bar image as a jpg file. Overwrites a file already existing in filesystem. https://stackoverflow.com/questions/7451183/how-to-create-image-file\ -from-qgraphicsscene-qgraphicsview#11642517 Args: fn: Filename Returns: True on success """ size = self.size pixelsx = max(1200, size[0]) pixelsy = int(pixelsx*size[1]/size[0]) imagesize = (pixelsx, pixelsy) image = QImage(pixelsx, pixelsy, QImage.Format_ARGB32_Premultiplied) painter = QPainter(image) painter.setRenderHint(QPainter.Antialiasing) painter.setBrush(Qt.white) painter.setPen(Qt.white) painter.drawRect(QRect(0, 0, *imagesize)) targetrect = QRectF(0, 0, *imagesize) sourcerect = QRectF(0, 0, *size) self.render(painter, targetrect, sourcerect) painter.end() return image.save(fn)
def testQRectWithFull(self): '''QFontMetrics.boundingRect(QRect, ...) - all arguments''' arg = QRect(0, 0, 100, 200) rect = self.metrics.boundingRect(arg, Qt.TextExpandTabs | Qt.AlignLeft, 'PySide by INdT', 20, [1, 2, 3, 4, 5]) self.assertTrue(isinstance(rect, QRect))
def testDrawTextWithRect(self): # bug #225 rect = QRect(100, 100, 100, 100) newRect = self.painter.drawText(rect, Qt.AlignCenter | Qt.TextWordWrap, self.text) self.assert_(isinstance(newRect, QRect))
def __init__(self, define_path='', define_type=None): super(MTTFilterFileDialog, self).__init__(get_maya_window()) self.supported_node_type = sorted([ node_type for (node_type, nice, attr) in MTTSettings.SUPPORTED_TYPE ]) self.defined_path = (define_path if os.path.isdir(define_path) or define_path == SOURCEIMAGES_TAG else None) self.defined_type = (define_type if define_type in self.supported_node_type else None) self.path_edit = None self.filter_reset_btn = None self.filter_line = None self.parent_folder_btn = None self.files_model = None self.files_list = None self.bookmark_list = None self.bookmark_list_sel_model = None self.types = None # move window to cursor position win_geo = MTTSettings.value('FilterFileDialog/windowGeometry', QRect(0, 0, 400, 300)) self.setGeometry(win_geo) mouse_pos = QCursor.pos() mouse_pos.setX(mouse_pos.x() - (win_geo.width() * 0.5)) self.move(mouse_pos) self.__create_ui() self.filter_line.setFocus() self.on_change_root_path(self.defined_path or SOURCEIMAGES_TAG)
def __init__(self): QWidget.__init__(self) self.setGeometry(QRect(100, 100, 400, 200)) self.layout = QtGui.QGridLayout(self) #lblCorporateEventType self.lblCorporateEventType = QLabel("Type") self.layout.addWidget(self.lblCorporateEventType, 0, 0) #cmbCorporateEventType self.cmbCorporateEventType = QComboBox(self) corporateEventTypeList = DaoCorporateEvent().getCorporateEventTypeList( ) for (corporateEventType) in corporateEventTypeList: self.cmbCorporateEventType.addItem(corporateEventType[1], corporateEventType[0]) self.layout.addWidget(self.cmbCorporateEventType, 0, 1) #lblAssetName self.lblAssetName = QLabel("Asset Name") self.layout.addWidget(self.lblAssetName, 1, 0) #cmdAssetName self.cmdAssetName = QComboBox(self) assetNameList = DaoAsset().getAssetNames('EQUITY') for (assetName) in assetNameList: self.cmdAssetName.addItem(assetName[1], assetName[0]) self.layout.addWidget(self.cmdAssetName, 1, 1) #lblCustody self.lblCustody = QLabel("Custody") self.layout.addWidget(self.lblCustody, 2, 0) #cmbCustody self.cmbCustody = QComboBox(self) custodyList = DaoCustody().getCustodyList() for (row) in custodyList: self.cmbCustody.addItem(row[1], row[0]) self.layout.addWidget(self.cmbCustody, 2, 1) #lblGrossAmount self.lblGrossAmount = QLabel("Gross Amount") self.layout.addWidget(self.lblGrossAmount, 3, 0) #txtGrossAmount self.txtGrossAmount = QLineEdit(self) self.txtGrossAmount.setValidator(QDoubleValidator( 0, 99999999, 6, self)) self.layout.addWidget(self.txtGrossAmount, 3, 1) #lblPaymentDate self.lblPaymentDate = QLabel("Payment Date") self.layout.addWidget(self.lblPaymentDate, 4, 0) #cmbPaymentDate self.cmbPaymentDate = QDateEdit(self) self.cmbPaymentDate.setDisplayFormat("dd-MM-yyyy") self.cmbPaymentDate.setDate(datetime.datetime.now()) self.layout.addWidget(self.cmbPaymentDate, 4, 1) #btnAdd self.btnAdd = QPushButton("Add", self) self.layout.addWidget(self.btnAdd) #btnClear self.btnClear = QPushButton("Clear", self) self.layout.addWidget(self.btnClear) #clearEditor self.clearEditor() self.initListener()
def numberbarPaint(self, number_bar, event): """Paints the line numbers of the code file""" self.number_bar.link = [] font_metrics = self.getWidget().fontMetrics() current_line = self.getWidget().document().findBlock( self.getWidget().textCursor().position()).blockNumber() + 1 block = self.getWidget().firstVisibleBlock() line_count = block.blockNumber() painter = QPainter(self.number_bar) # TODO: second argument is color -> to settings painter.fillRect(self.number_bar.rect(), self.getWidget().palette().base()) # Iterate over all visible text blocks in the document. while block.isValid(): line_count += 1 text = str(line_count) block_top = self.getWidget().blockBoundingGeometry( block).translated(self.getWidget().contentOffset()).top() if not block.isVisible(): block = block.next() while not block.isVisible(): line_count += 1 block = block.next() continue self.number_bar.link.append((block_top, line_count)) # Check if the position of the block is out side of the visible # area. if block_top >= event.rect().bottom(): break # We want the line number for the selected line to be bold. if line_count == current_line: font = painter.font() font.setBold(True) else: font = painter.font() font.setBold(False) # line opens a block if line_count in self.hidden: text += "+" font.setUnderline(True) elif block.text().count("(") > block.text().count(")"): text += "-" font.setUnderline(True) else: font.setUnderline(False) painter.setFont(font) # Draw the line number right justified at the position of the # line. paint_rect = QRect(0, block_top, self.number_bar.width(), font_metrics.height()) painter.drawText(paint_rect, Qt.AlignLeft, text) block = block.next() painter.end()
def paintEvent(self, event): """ Paints the widget """ if self.enabled is False: return Panel.paintEvent(self, event) painter = QPainter(self) painter.fillRect(event.rect(), self.back_brush) for vb in self.editor.codeEdit.visible_blocks: line = vb.row # paint marker for line marker = self.getIndicatorForLine(line) if marker is None: continue # use the normal pen to draw the fold indicator drawLines = False pen = self.normal_pen if marker.hover is True: pen = self.highlight_pen drawLines = True painter.setPen(pen) # get the text to draw txt = '-' if marker.folded is True: drawLines = False txt = '+' offset = 4 h = self.size_hint.height() fm = QFontMetricsF(self.editor.codeEdit.font()) hoffset = (fm.height() - h) / 2.0 r = QRect(vb.rect.x(), vb.rect.y() + hoffset, self.size_hint.width(), self.size_hint.height()) painter.setFont(self.font) painter.drawText(r, Qt.AlignVCenter | Qt.AlignHCenter, txt) w = self.size_hint.width() - 2 * offset h = self.size_hint.width() - 2 * offset hoffset = (fm.height() - h) / 2.0 r.setX(vb.rect.x() + offset) r.setY(vb.rect.y() + hoffset) r.setWidth(w) r.setHeight(h) painter.drawRect(r) if drawLines is True: top = (vb.rect.x() + self.size_hint.width() / 2.0, vb.rect.y() + hoffset + offset * 2) delta = ((marker.end - marker.start) * vb.height) # - (vb.rect.height() / 2.0) bottom = (top[0], top[1] + delta) painter.drawLine(top[0], top[1], bottom[0], bottom[1]) painter.drawLine(bottom[0], bottom[1], bottom[0] + self.size_hint.width() / 2.0, bottom[1]) return
def __layoutActions(self): if self._layout == None: self._layout = dict() actions = self.actions() count = len(actions) angleStep = 2.0 * math.pi / float(count) angle = 0 fontMetrics = QtGui.QFontMetrics(self.font()) radius = 120 bounds = QRect() for a in actions: r = fontMetrics.boundingRect(a.text()).adjusted(-8, -8, 8, 8) r = r.translated(radius * math.cos(angle), radius * math.sin(angle)) r = r.translated(-r.width() / 2, -r.height() / 2) r = r.translated(self.width() / 2, self.height() / 2) self._layout[a] = r bounds |= r angle += angleStep bounds = bounds.adjusted(-self._lineWidth, -self._lineWidth, self._lineWidth, self._lineWidth) for a in self._layout.keys(): r = self._layout[a] r.translate(-bounds.x(), -bounds.y()) self.resize(bounds.width(), bounds.height())
def scene_box_added(self, rect): """The user added a box """ m = self.model() row = len(self._rows) if not m.insertRow(row): raise InselectError('Could not insert row') else: # Cumbersome conversion to ints rect = QRect(rect.left(), rect.top(), rect.width(), rect.height()) if not m.setData(m.index(row, 0), rect, RectRole): raise InselectError('Could not set rect') else: # Select the new box self.scene.clearSelection() item = self.items_of_rows([row]).next() item.setSelected(True) item.update()
def checkBoxRect(self, opt, editor): cb_option = QStyleOptionButton() style = QApplication.style() cb_rect = style.subElementRect(QStyle.SE_CheckBoxIndicator, cb_option, editor) cb_point = QPoint( opt.rect.x() + (opt.rect.width() - cb_rect.width()) / 2, opt.rect.y() + (opt.rect.height() - cb_rect.height()) / 2) return QRect(cb_point, cb_rect.size())
def boundingRect(self): if not self.node_from or not self.node_to: return QRect() n1 = self.node_from() n2 = self.node_to() if n1 is None or n2 is None: return QRect() node_from_pos = n1.pos() node_to_pos = n2.pos() bbox = QRect(min(node_from_pos.x(), node_to_pos.x()), min(node_from_pos.y(), node_to_pos.y()), abs(node_from_pos.x() - node_to_pos.x()), abs(node_from_pos.y() - node_to_pos.y())) return bbox
def testGetCoordsAndRect(self): rect1 = QRect(1, 2, 3, 4) self.assertEqual(rect1.getRect(), (1, 2, 3, 4)) self.assertEqual(rect1.getCoords(), (1, 2, 3, 5)) rect1 = QRectF(1, 2, 3, 4) self.assertEqual(rect1.getRect(), (1, 2, 3, 4)) self.assertEqual(rect1.getCoords(), (1, 2, 4, 6))
def draw_no_data(self, painter): text_pen = QPen() text_pen.setCapStyle(Qt.RoundCap) text_pen.setColor(QColor(128, 128, 128)) # alpha=255=fully opaque text_pen.setWidth(1) painter.setPen(text_pen) painter.setFont(self.title_font) r = QRect( self.margin, 0, self.width() - 2*self.margin, self.height()) painter.drawText(r, (Qt.AlignCenter | Qt.AlignLeft) + Qt.TextWordWrap, _("No data"))
def getCheckBoxRect(self, option): check_box_style_option = QStyleOptionButton() check_box_rect = QApplication.style().subElementRect( QStyle.SE_CheckBoxIndicator, check_box_style_option, None) check_box_point = QPoint( option.rect.x() + option.rect.width() / 2 - check_box_rect.width() / 2, option.rect.y() + option.rect.height() / 2 - check_box_rect.height() / 2) return QRect(check_box_point, check_box_rect.size())
def paintEvent(self, event): painter = QStylePainter(self) # ticks opt = QStyleOptionSlider() self.initStyleOption(opt) opt.subControls = QStyle.SC_SliderTickmarks painter.drawComplexControl(QStyle.CC_Slider, opt) # groove opt.sliderPosition = 20 opt.sliderValue = 0 opt.subControls = QStyle.SC_SliderGroove painter.drawComplexControl(QStyle.CC_Slider, opt) # handle rects opt.sliderPosition = self.lowerPos lr = self.style().subControlRect(QStyle.CC_Slider, opt, QStyle.SC_SliderHandle, self) lrv = self.pick(lr.center()) opt.sliderPosition = self.upperPos ur = self.style().subControlRect(QStyle.CC_Slider, opt, QStyle.SC_SliderHandle, self) urv = self.pick(ur.center()) # span minv = min(lrv, urv) maxv = max(lrv, urv) c = self.style().subControlRect(QStyle.CC_Slider, opt, QStyle.SC_SliderGroove, self).center() spanRect = QRect(QPoint(c.x() - 2, minv), QPoint(c.x() + 1, maxv)) if self.orientation() == QtCore.Qt.Horizontal: spanRect = QRect(QPoint(minv, c.y() - 2), QPoint(maxv, c.y() + 1)) self.drawSpan(painter, spanRect) # handles if self.lastPressed == QxtSpanSlider.LowerHandle: self.drawHandle(painter, QxtSpanSlider.UpperHandle) self.drawHandle(painter, QxtSpanSlider.LowerHandle) else: self.drawHandle(painter, QxtSpanSlider.LowerHandle) self.drawHandle(painter, QxtSpanSlider.UpperHandle)
def absoluteGeometry(self): """A fix to get the element to return it's absolute geometry, instead of it's geometry relative to it's parent frame""" if self._geometry_calculated: return self._geometry if self._element.isNull(): return None elem = self._element elem_geom = QRect(elem.geometry()) elem_webframe = elem.webFrame() elem_wf_geom = QRect(elem_webframe.geometry()) elem_geom.moveTopLeft(elem_geom.topLeft() - elem_wf_geom.topLeft()) wf_parent = elem_webframe.parentFrame() while wf_parent: wf_parent_geom = wf_parent.geometry() elem_geom.moveTopLeft(elem_geom.topLeft() - wf_parent_geom.topLeft()) self._geometry = elem_geom self._geometry_calculated = True return elem_geom
def paintEvent(self, pe): painter = QPainter(self) painter.save() background = QColor(55, 55, 55) brush = QBrush(background) painter.setOpacity(self._opacity) painter.setBrush(brush) painter.setPen(Qt.NoPen) painter.drawRect(self.rect()) painter.restore() # draw a bottom border painter.setPen(Qt.black) painter.drawLine(0, self.height(), self.width(), self.height()) # now the text pen = QPen(Qt.white) pen.setWidth(16) painter.setPen(pen) painter.setFont(QFont("Trebuchet MS", 16, QFont.Bold)) text_rect = QRect(self.rect()) text_rect.adjust(self._margin, self._margin, self._margin, self._margin) painter.drawText(text_rect, Qt.AlignLeft, self._message_str)
def __layoutActions(self): if self._layout == None: self._layout = dict() actions = self.actions() count = len(actions) angleStep = 2.0*math.pi/float(count) angle = 0 fontMetrics = QtGui.QFontMetrics(self.font()) radius = 120 bounds = QRect() for a in actions: r = fontMetrics.boundingRect(a.text()).adjusted(-8, -8, 8, 8) r = r.translated(radius*math.cos(angle), radius*math.sin(angle)) r = r.translated(-r.width()/2, -r.height()/2) r = r.translated(self.width()/2, self.height()/2) self._layout[a] = r bounds |= r angle += angleStep bounds = bounds.adjusted(-self._lineWidth, -self._lineWidth, self._lineWidth, self._lineWidth) for a in self._layout.keys(): r = self._layout[a] r.translate(-bounds.x(), -bounds.y()) self.resize(bounds.width(), bounds.height())
def paintEvent(self, event): """ Paints the widget """ if self.enabled is False: return Panel.paintEvent(self, event) painter = QPainter(self) painter.fillRect(event.rect(), self.back_brush) for vb in self.editor.codeEdit.visible_blocks: l = vb.row marker = self.__getMarkerForLine(l) if marker: if marker.icon is not None: r = QRect() r.setX(vb.rect.x()) r.setY(vb.rect.y()) r.setWidth(self.size_hint.width()) r.setHeight(self.size_hint.height()) marker.icon.paint(painter, r) return
def getInfo(self): """TOWRITE""" # TODO: generate a temporary pattern from the scene data. # TODO: grab this information from the pattern self.stitchesTotal = 5 # TODO: embStitchList_count(pattern->stitchList, TOTAL) self.stitchesReal = 4 # TODO: embStitchList_count(pattern->stitchList, NORMAL) self.stitchesJump = 3 # TODO: embStitchList_count(pattern->stitchList, JUMP) self.stitchesTrim = 2 # TODO: embStitchList_count(pattern->stitchList, TRIM) self.colorTotal = 1 # TODO: embThreadList_count(pattern->threadList, TOTAL) self.colorChanges = 0 # TODO: embThreadList_count(pattern->threadList, CHANGES) self.boundingRect = QRect() #TODO/FIXME# self.boundingRect.setRect(0, 0, 50, 100) # TODO: embPattern_calcBoundingBox(pattern)
def roundCorners(rectangle, radius): '''Get region for setting round edges mask''' region = QRegion() region += rectangle.adjusted(radius,0,-radius,0) region += rectangle.adjusted(0,radius,-0,-radius) corner = QRect(rectangle.topLeft(), QSize(radius*2,radius*2)) region += QRegion(corner, QRegion.Ellipse) corner.moveTopRight(rectangle.topRight()) region += QRegion(corner, QRegion.Ellipse) corner.moveBottomLeft(rectangle.bottomLeft()) region += QRegion(corner, QRegion.Ellipse) corner.moveBottomRight(rectangle.bottomRight()) region += QRegion(corner, QRegion.Ellipse) return region
def mask(rect, r): region = QRegion() region += rect.adjusted(r, 0, -r, 0) region += rect.adjusted(0, r, 0, -r) # top left corner = QRect(rect.topLeft(), QSize(r * 2, r * 2)) region += QRegion(corner, QRegion.Ellipse) # top right corner.moveTopRight(rect.topRight()) region += QRegion(corner, QRegion.Ellipse) # bottom left corner.moveBottomLeft(rect.bottomLeft()) region += QRegion(corner, QRegion.Ellipse) # bottom right corner.moveBottomRight(rect.bottomRight()) region += QRegion(corner, QRegion.Ellipse) return region
def __giveUpSomeLeftoverSpace(self, neededArea): """ Sacrifice some leftover space to represent the neededARea""" thisDir = self.__updateDirectionToPreferSquareness(neededArea) giveUpFns = [self.__giveUpLeftoverWidth, self.__giveUpLeftoverHeight] fn = giveUpFns[thisDir] newRect = QRect() newRect.setTopLeft(self.leftoverRect.topLeft()) (width, height) = (self.leftoverRect.width(), self.leftoverRect.height()) (width, height) = fn(neededArea, width, height) if not self.leftoverRect.isValid() and not self.leftoverRect.isEmpty(): print "Failure with the following input" print "W/H %i/%i" % (width, height) print "ParentRect %s" % repr(self.parentRect) print "Leftover %s" % repr(self.leftoverRect) print "Percentages %s" % repr(self.percs) assert False newRect.setHeight(height) newRect.setWidth(width) return newRect
class EmbDetailsDialog(QDialog): """ Subclass of `QDialog`_ Class implementing the Details dialog. .. sphinx_generate_methods_summary:: EmbDetailsDialog """ def __init__(self, theScene, parent): """ Default class constructor. :param `theScene`: TOWRITE :type `theScene`: `QGraphicsScene`_ :param `parent`: Pointer to a parent widget instance. :type `parent`: `QWidget`_ """ super(EmbDetailsDialog, self).__init__(parent) self.setMinimumSize(750, 550) self.getInfo() mainWidget = self.createMainWidget() buttonBox = QDialogButtonBox(QDialogButtonBox.Ok) buttonBox.accepted.connect(self.accept) vboxLayoutMain = QVBoxLayout(self) vboxLayoutMain.addWidget(mainWidget) vboxLayoutMain.addWidget(buttonBox) self.setLayout(vboxLayoutMain) self.setWindowTitle(self.tr("Embroidery Design Details")) QApplication.setOverrideCursor(Qt.ArrowCursor) def __del__(self): """Class destructor""" QApplication.restoreOverrideCursor() def getInfo(self): """TOWRITE""" # TODO: generate a temporary pattern from the scene data. # TODO: grab this information from the pattern self.stitchesTotal = 5 # TODO: embStitchList_count(pattern->stitchList, TOTAL) self.stitchesReal = 4 # TODO: embStitchList_count(pattern->stitchList, NORMAL) self.stitchesJump = 3 # TODO: embStitchList_count(pattern->stitchList, JUMP) self.stitchesTrim = 2 # TODO: embStitchList_count(pattern->stitchList, TRIM) self.colorTotal = 1 # TODO: embThreadList_count(pattern->threadList, TOTAL) self.colorChanges = 0 # TODO: embThreadList_count(pattern->threadList, CHANGES) self.boundingRect = QRect() #TODO/FIXME# self.boundingRect.setRect(0, 0, 50, 100) # TODO: embPattern_calcBoundingBox(pattern) def createMainWidget(self): """ TOWRITE :return: TOWRITE :rtype: `QScrollArea`_ """ widget = QWidget(self) # Misc groupBoxMisc = QGroupBox(self.tr("General Information"), widget) labelStitchesTotal = QLabel(self.tr("Total Stitches:"), self) labelStitchesReal = QLabel(self.tr("Real Stitches:"), self) labelStitchesJump = QLabel(self.tr("Jump Stitches:"), self) labelStitchesTrim = QLabel(self.tr("Trim Stitches:"), self) labelColorTotal = QLabel(self.tr("Total Colors:"), self) labelColorChanges = QLabel(self.tr("Color Changes:"), self) labelRectLeft = QLabel(self.tr("Left:"), self) labelRectTop = QLabel(self.tr("Top:"), self) labelRectRight = QLabel(self.tr("Right:"), self) labelRectBottom = QLabel(self.tr("Bottom:"), self) labelRectWidth = QLabel(self.tr("Width:"), self) labelRectHeight = QLabel(self.tr("Height:"), self) fieldStitchesTotal = QLabel(u'%s' % (self.stitchesTotal), self) fieldStitchesReal = QLabel(u'%s' % (self.stitchesReal), self) fieldStitchesJump = QLabel(u'%s' % (self.stitchesJump), self) fieldStitchesTrim = QLabel(u'%s' % (self.stitchesTrim), self) fieldColorTotal = QLabel(u'%s' % (self.colorTotal), self) fieldColorChanges = QLabel(u'%s' % (self.colorChanges), self) fieldRectLeft = QLabel(u'%s' % (str(self.boundingRect.left()) + " mm"), self) fieldRectTop = QLabel(u'%s' % (str(self.boundingRect.top()) + " mm"), self) fieldRectRight = QLabel(u'%s' % (str(self.boundingRect.right()) + " mm"), self) fieldRectBottom = QLabel(u'%s' % (str(self.boundingRect.bottom()) + " mm"), self) fieldRectWidth = QLabel(u'%s' % (str(self.boundingRect.width()) + " mm"), self) fieldRectHeight = QLabel(u'%s' % (str(self.boundingRect.height()) + " mm"), self) gridLayoutMisc = QGridLayout(groupBoxMisc) gridLayoutMisc.addWidget(labelStitchesTotal, 0, 0, Qt.AlignLeft) gridLayoutMisc.addWidget(labelStitchesReal, 1, 0, Qt.AlignLeft) gridLayoutMisc.addWidget(labelStitchesJump, 2, 0, Qt.AlignLeft) gridLayoutMisc.addWidget(labelStitchesTrim, 3, 0, Qt.AlignLeft) gridLayoutMisc.addWidget(labelColorTotal, 4, 0, Qt.AlignLeft) gridLayoutMisc.addWidget(labelColorChanges, 5, 0, Qt.AlignLeft) gridLayoutMisc.addWidget(labelRectLeft, 6, 0, Qt.AlignLeft) gridLayoutMisc.addWidget(labelRectTop, 7, 0, Qt.AlignLeft) gridLayoutMisc.addWidget(labelRectRight, 8, 0, Qt.AlignLeft) gridLayoutMisc.addWidget(labelRectBottom, 9, 0, Qt.AlignLeft) gridLayoutMisc.addWidget(labelRectWidth, 10, 0, Qt.AlignLeft) gridLayoutMisc.addWidget(labelRectHeight, 11, 0, Qt.AlignLeft) gridLayoutMisc.addWidget(fieldStitchesTotal, 0, 1, Qt.AlignLeft) gridLayoutMisc.addWidget(fieldStitchesReal, 1, 1, Qt.AlignLeft) gridLayoutMisc.addWidget(fieldStitchesJump, 2, 1, Qt.AlignLeft) gridLayoutMisc.addWidget(fieldStitchesTrim, 3, 1, Qt.AlignLeft) gridLayoutMisc.addWidget(fieldColorTotal, 4, 1, Qt.AlignLeft) gridLayoutMisc.addWidget(fieldColorChanges, 5, 1, Qt.AlignLeft) gridLayoutMisc.addWidget(fieldRectLeft, 6, 1, Qt.AlignLeft) gridLayoutMisc.addWidget(fieldRectTop, 7, 1, Qt.AlignLeft) gridLayoutMisc.addWidget(fieldRectRight, 8, 1, Qt.AlignLeft) gridLayoutMisc.addWidget(fieldRectBottom, 9, 1, Qt.AlignLeft) gridLayoutMisc.addWidget(fieldRectWidth, 10, 1, Qt.AlignLeft) gridLayoutMisc.addWidget(fieldRectHeight, 11, 1, Qt.AlignLeft) gridLayoutMisc.setColumnStretch(1,1) groupBoxMisc.setLayout(gridLayoutMisc) # TODO: Color Histogram # Stitch Distribution # groupBoxDist = QGroupBox(self.tr("Stitch Distribution"), widget) # TODO: Stitch Distribution Histogram # Widget Layout vboxLayoutMain = QVBoxLayout(widget) vboxLayoutMain.addWidget(groupBoxMisc) # vboxLayoutMain.addWidget(groupBoxDist) vboxLayoutMain.addStretch(1) widget.setLayout(vboxLayoutMain) scrollArea = QScrollArea(self) scrollArea.setWidgetResizable(True) scrollArea.setWidget(widget) return scrollArea
def _drawLeafRow(self, option, painter, index): """ @type painter: QPainter @type option: QStyleOptionViewItemV4 @type index: QModelIndex """ rect = option.rect if self.selectionModel().isSelected(index): painter.fillRect(rect, Qt.white) else: painter.fillRect(rect, QColor(Qt.lightGray).lighter(120)) painter.setPen(Qt.darkGray) painter.drawLine(rect.bottomLeft(), rect.bottomRight()) painter.setPen(QColor(Qt.lightGray).lighter()) painter.drawLine(rect.topLeft(), rect.topRight()) ex = index.data(Qt.UserRole) painter.setPen(Qt.black) painter.save() font = painter.font() font.setBold(True) painter.setFont(font) painter.drawText(rect.adjusted(LEFT_MARGIN, 0, 0, -rect.height() / 2), Qt.AlignVCenter, ex.desc) painter.restore() painter.setPen(Qt.darkGray) painter.setRenderHint(QPainter.Antialiasing) if self._idToName is not None: fromName = self._idToName(ex.fromId) fromRect = painter.fontMetrics().boundingRect(fromName) painter.setBrush(Qt.lightGray) painter.setPen(Qt.transparent) bottomRect = rect.adjusted(LEFT_MARGIN, rect.height() / 2, 0, 0) fromRect = fromRect.adjusted(-4, -2, 4, 2) fromRect = QRect(bottomRect.left(), bottomRect.top(), fromRect.width(), fromRect.height()) painter.drawRoundedRect(fromRect, 3, 3) painter.setPen(Qt.darkGray) painter.drawText(fromRect.adjusted(4, 2, -4, -2), Qt.AlignVCenter, fromName) painter.save() # FIXME: normal check for weekly and income envelopes, colors to constants if not ex.manual: painter.setBrush(QColor(157, 157, 157)) elif fromName.startswith("Week_"): painter.setBrush(Qt.transparent) elif fromName.lower() == u"доход" or fromName.lower() == u"income": painter.setBrush(QColor(100, 230, 100)) else: painter.setBrush(QColor(120, 120, 230)) painter.setPen(Qt.transparent) painter.drawRect(QRect(0, rect.top() + 4, 4, rect.height() - 10)) painter.restore() bottomRect = bottomRect.adjusted(fromRect.width() + MARGIN, 0, 0, 0) toName = self._idToName(ex.toId) toRect = painter.fontMetrics().boundingRect(toName) toRect = toRect.adjusted(-4, -2, 4, 2) toRect = QRect(bottomRect.left(), bottomRect.top(), toRect.width(), toRect.height()) painter.setPen(Qt.transparent) painter.drawRoundedRect(toRect, 3, 3) painter.setPen(Qt.darkGray) painter.drawText(toRect.adjusted(4, 2, -4, -2), Qt.AlignVCenter, toName) font = painter.font() font.setPixelSize(24) font.setBold(True) painter.save() painter.setFont(font) painter.drawText(rect.adjusted(rect.width() / 2, 0, -5, 0), Qt.AlignRight | Qt.AlignVCenter, str(int(ex.value)) + u" руб.") painter.restore()
def reset(self): import copy self.lastFlipPercentage = 100 self.currPercItem = 0 self.leftoverRect = QRect(self.parentRect)
def __init__(self, parentRect, percentageItems): self.parentRect = self.leftoverRect = QRect() self.percItems = sorted(percentageItems, key=lambda pItem: pItem.getLocalPercentage(), reverse = True) self.parentRect = QRect(parentRect) self.reset() self.percs = []
def _paint_crop(self, painter, option, index): """Paints the crop """ source_rect = index.data(RectRole) crop_rect = self.crop_rect.translated(option.rect.topLeft()) angle = index.data(RotationRole) # Target rect with same aspect ratio as source source_aspect = float(source_rect.width()) / source_rect.height() crop_aspect = float(crop_rect.width()) / crop_rect.height() # True if the item has been rotated by a multiple of 90 degrees perpendicular = 1 == (angle / 90) % 2 # Some nasty logic to compute the target rect if perpendicular: crop_aspect = 1.0 / crop_aspect if source_aspect > 1.0: # Crop is wider than is is tall if crop_aspect > source_aspect: fit_to = 'height' f = 1.0 / source_aspect else: fit_to = 'width' f = source_aspect else: # Crop is taller than is is wide if crop_aspect < source_aspect: fit_to = 'width' f = source_aspect else: fit_to = 'height' f = 1.0 / source_aspect if perpendicular: if 'width' == fit_to: size = QSize(crop_rect.height(), crop_rect.height() / f) else: size = QSize(crop_rect.width() / f, crop_rect.width()) else: if 'width' == fit_to: size = QSize(crop_rect.width(), crop_rect.width() / f) else: size = QSize(crop_rect.height() / f, crop_rect.height()) target_rect = QRect(crop_rect.topLeft(), size) target_rect.moveCenter(option.rect.center()) # Draw rotated if angle: t = QTransform() t.translate(option.rect.width() / 2+option.rect.left(), option.rect.height() / 2+option.rect.top()) t.rotate(angle) t.translate(-option.rect.width() / 2-option.rect.left(), -option.rect.height() / 2-option.rect.top()) with painter_state(painter): if angle: painter.setTransform(t) painter.drawPixmap(target_rect, index.data(PixmapRole), source_rect) if QStyle.State_Selected & option.state: painter.setPen(QPen(Qt.white, 1, Qt.SolidLine)) painter.drawRect(target_rect)
def testDefault(self): #QRect() obj = QRect() self.assert_(obj.isNull())
class PaletteWidget(QtGui.QWidget): # Colour changed signal changed = QtCore.Signal() @property def colour(self): return QtGui.QColor.fromHsvF(self._hue, self._saturation, self._value) @colour.setter def colour(self, value): # If this is an integer, assume is RGBA if type(value) is int: r = (value & 0xff000000) >> 24 g = (value & 0xff0000) >> 16 b = (value & 0xff00) >> 8 value = QtGui.QColor.fromRgb(r,g,b) self._set_colour(value) def __init__(self, parent = None): super(PaletteWidget, self).__init__(parent) self._hue = 1.0 self._saturation = 1.0 self._value = 1.0 self._hue_width = 24 self._gap = 8 self._colour = QtGui.QColor.fromHslF(self._hue, 1.0, 1.0) self._calculate_bounds() self._draw_palette() # Calculate the sizes of various bits of our UI def _calculate_bounds(self): width = self.width() height = self.height() # Hue palette self._hue_rect = QRect( width-self._hue_width, 0, self._hue_width, height) # Shades palette self._shades_rect = QRect( 0, 0, width-(self._hue_width+self._gap), height) # Render our palette to an image def _draw_palette(self): # Create an image with a white background self._image = QtGui.QImage(QtCore.QSize(self.width(), self.height()), QtGui.QImage.Format.Format_RGB32) self._image.fill(QtGui.QColor.fromRgb(0xff, 0xff, 0xff)) # Draw on our image with no pen qp = QtGui.QPainter() qp.begin(self._image) qp.setPen(QtCore.Qt.NoPen) # Render hues rect = self._hue_rect for x in xrange(rect.x(), rect.x()+rect.width()): for y in xrange(rect.y(), rect.y()+rect.height(), 8): h = float(y)/rect.height() s = 1.0 v = 1.0 c = QtGui.QColor.fromHsvF(h, s, v) qp.setBrush(c) qp.drawRect(x, y, 8, 8) # Render hue selection marker qp.setBrush(QtGui.QColor.fromRgb(0xff, 0xff, 0xff)) qp.drawRect(rect.x(), self._hue * rect.height(), rect.width(), 2) # Render shades rect = self._shades_rect width = float(rect.width()) steps = int(round(width / 8.0)) step_size = width / steps x = rect.x() while x < rect.width()+rect.x(): w = int(round(step_size)) for y in xrange(rect.y(), rect.y()+rect.height(), 8): h = self._hue s = 1-float(y)/rect.height() v = float(x)/rect.width() c = QtGui.QColor.fromHsvF(h, s, v) qp.setBrush(c) qp.drawRect(x, y, w, 8) x += w width -= w steps -= 1 if steps > 0: step_size = width / steps # Render colour selection marker qp.setBrush(QtGui.QColor.fromRgb(0xff, 0xff, 0xff)) qp.drawRect(rect.x(), (1-self._saturation)*rect.height(), rect.width(), 1) qp.drawRect(self._value*rect.width(), rect.y(), 1, rect.height()) qp.end() def paintEvent(self, event): # Render our palette image to the screen qp = QtGui.QPainter() qp.begin(self) qp.drawImage(QPoint(0,0), self._image) qp.end() def mousePressEvent(self, event): mouse = QPoint(event.pos()) if event.buttons() & QtCore.Qt.LeftButton: # Click on hues? if self._hue_rect.contains(mouse.x(), mouse.y()): y = mouse.y() c = QtGui.QColor.fromHsvF( float(y)/self.height(), self._saturation, self._value) self.colour = c # Click on colours? elif self._shades_rect.contains(mouse.x(), mouse.y()): # calculate saturation and value x = mouse.x() y = mouse.y() c = QtGui.QColor.fromHsvF( self._hue, 1-float(y)/self._shades_rect.height(), float(x)/self._shades_rect.width()) self.colour = c def mouseMoveEvent(self, event): if event.buttons() & QtCore.Qt.LeftButton: self.mousePressEvent(event) def resizeEvent(self, event): self._calculate_bounds() self._draw_palette() # Set the current colour def _set_colour(self, c): h, s, v, _ = c.getHsvF() self._hue = h self._saturation = s self._value = v self._draw_palette() self.repaint() self.changed.emit()
class PackedRect: """ Given p and a starting rect, draw a subrectangle that takes <= p% of the area of the starting rect. Repeat for p1,p2... as long as there continues to be room in the parent rect""" def __init__(self, parentRect, percentageItems): self.parentRect = self.leftoverRect = QRect() self.percItems = sorted(percentageItems, key=lambda pItem: pItem.getLocalPercentage(), reverse = True) self.parentRect = QRect(parentRect) self.reset() self.percs = [] def __iter__(self): return self def next(self): perc = 0 if self.currPercItem < len(self.percItems) and not self.isEmpty(): while perc == 0: if self.currPercItem < len(self.percItems): percItem = self.percItems[self.currPercItem] perc = percItem.getLocalPercentage() else: raise StopIteration() self.currPercItem += 1 return (percItem, self.nextRect(perc)) else: raise StopIteration() def reset(self): import copy self.lastFlipPercentage = 100 self.currPercItem = 0 self.leftoverRect = QRect(self.parentRect) def __updateDirectionToPreferSquareness(self, neededArea): """ Pick a direction that will give a more square result for the next rectangle, but strongly bias toward horizontal. Its important for there to be consistency in this algorithm and not have it depend on any weird side effects """ biasTowardHoriz = 1.5 (width, height) = (self.leftoverRect.width(),self.leftoverRect.height()) (width, height) = self.__calculaceGivingUpWidth(neededArea, width, height) widthDiff = abs(width-height) (width, height) = (self.leftoverRect.width(),self.leftoverRect.height()) (width, height) = self.__calculateGivingUpHeight(neededArea, width, height) heightDiff = abs(width-height) if widthDiff < (heightDiff * biasTowardHoriz): return Direction.Horizontal else: return Direction.Vertical def isEmpty(self): return self.leftoverRect.isEmpty() def __isNeededAreaMoreThanLeftover(self, neededArea): leftoverArea = self.leftoverRect.width() * self.leftoverRect.height() return (neededArea + 0.01) > leftoverArea @validRectReturned def __giveUpAllRemainingArea(self): """ Return all remaining leftover space and empty the leftover rect""" assert not self.leftoverRect.isEmpty() remaining = QRect(self.leftoverRect) self.leftoverRect.setWidth(-1) self.leftoverRect.setHeight(-1) assert self.leftoverRect.isEmpty() return remaining def __calculateGivingUpHeight(self, neededArea, width, height): height = neededArea / width height = ceil(height) return (width, height) def __calculaceGivingUpWidth(self, neededArea, width, height): width = neededArea / height width = ceil(width) return (width, height) def __giveUpLeftoverHeight(self, neededArea, width, height): """ Sacrifice some height from the leftover rect for the needed area""" (width, height) = self.__calculateGivingUpHeight(neededArea, width, height) self.leftoverRect.setY(self.leftoverRect.y() + height) return (width, height) def __giveUpLeftoverWidth(self, neededArea, width, height): """ Sacrifice some width from the leftover rect for the needed area""" (width, height) = self.__calculaceGivingUpWidth(neededArea, width, height) self.leftoverRect.setX(self.leftoverRect.x() + width) return (width, height) @validRectReturned def __giveUpSomeLeftoverSpace(self, neededArea): """ Sacrifice some leftover space to represent the neededARea""" thisDir = self.__updateDirectionToPreferSquareness(neededArea) giveUpFns = [self.__giveUpLeftoverWidth, self.__giveUpLeftoverHeight] fn = giveUpFns[thisDir] newRect = QRect() newRect.setTopLeft(self.leftoverRect.topLeft()) (width, height) = (self.leftoverRect.width(), self.leftoverRect.height()) (width, height) = fn(neededArea, width, height) if not self.leftoverRect.isValid() and not self.leftoverRect.isEmpty(): print "Failure with the following input" print "W/H %i/%i" % (width, height) print "ParentRect %s" % repr(self.parentRect) print "Leftover %s" % repr(self.leftoverRect) print "Percentages %s" % repr(self.percs) assert False newRect.setHeight(height) newRect.setWidth(width) return newRect @validRectReturned def nextRect(self, percentage): """ Get the next rect from leftoverRect, update leftoverRect with whats leftover """ self.percs.append(percentage) if self.isEmpty(): raise ValueError("This guy is empty pR: %s perc: %s" % (self.parentRect, self.percs)) neededArea = (self.parentRect.width() * self.parentRect.height()) * (percentage/100.0) if self.__isNeededAreaMoreThanLeftover(neededArea): return self.__giveUpAllRemainingArea() return self.__giveUpSomeLeftoverSpace(neededArea) def __repr__(self): return "PackedRect(%s)" % repr(self.parentRect) def __str__(self): return self.__repr__() + " Leftover(%s)" % repr(self.leftoverRect)