def mouseReleaseEvent(self, event): if self._start_sel: self._start_sel = False if self._sel_accepted: self.viewport().update(self.rubberBandRegion(self._sel_rect)) sceneRegion = self.mapToScene(self._sel_rect) self._sel_accepted = False self._sel_rect = QRect() event.accept() if self.scene(): self.scene().setPointCellSelection(sceneRegion) return elif self._first_point is not None: scene = self.scene() div_accepted = self._div_accepted if div_accepted: event.accept() self.viewport().update(self.lineSelectionRect(self._div_line)) if self._second_point is not None: scene.setDivisionLine(self._first_point, self._second_point) self._second_point.setSelected(False) self._first_point = None self._second_point = None self._div_line = QLine() self._div_accepted = False params = parameters.instance params.is_cell_editable = True if div_accepted: return QGraphicsView.mouseReleaseEvent(self, event)
def __init__(self, *args): QGraphicsView.__init__(self, *args) self._sel_rect = QRect() self._start_selection = None self._start_sel = False self._sel_accepted = False self._first_point = None self._second_point = None self._div_accepted = False self._div_line = QLine()
def paintEvent(event): painter = QPainter(self.label_image) painter.setRenderHint(QPainter.SmoothPixmapTransform, True) w = self.label_image.size().width() h = self.label_image.size().height() painter.scale(w / 80.0, h / 60.0) painter.drawImage(0, 0, self.image) if 35 != None and 45 != None: pen = QPen() pen.setColor(Qt.white) pen.setWidth(0.2) painter.setPen(pen) from_x, from_y, to_x, to_y = [35, 25, 45, 35] from_x = from_x * self.image_pixel_width + 1 from_y = from_y * self.image_pixel_width + 1 to_x = to_x * self.image_pixel_width + 1 to_y = to_y * self.image_pixel_width + 1 cross_x = from_x + (to_x - from_x) / 2.0 cross_y = from_y + (to_y - from_y) / 2.0 if to_x - from_x > 5 or to_y - from_y > 5: lines = [ QLine(from_x, from_y, from_x + self.crosshair_width, from_y), QLine(from_x, from_y, from_x, from_y + self.crosshair_width), QLine(to_x, to_y, to_x, to_y - self.crosshair_width), QLine(to_x, to_y, to_x - self.crosshair_width, to_y), QLine(from_x, to_y, from_x, to_y - self.crosshair_width), QLine(from_x, to_y, from_x + self.crosshair_width, to_y), QLine(to_x, from_y, to_x, from_y + self.crosshair_width), QLine(to_x, from_y, to_x - self.crosshair_width, from_y) ] painter.drawLines(lines) lines = [ QLine(cross_x - self.crosshair_width, cross_y, cross_x + self.crosshair_width, cross_y), QLine(cross_x, cross_y - self.crosshair_width, cross_x, cross_y + self.crosshair_width) ] painter.drawLines(lines) self.update_spotmeter_roi_label()
def updateXAxisLines(self): self.xAxisY = self.edgeMargin + self.plotHeight / 2 self.xAxisXStart = self.edgeMargin self.xAxisXEnd = self.width() - self.edgeMargin self.xAxisLines = [ QLine(self.xAxisXStart, self.xAxisY, self.xAxisXEnd, self.xAxisY) ]
def _arrange_data(self): self.rect = QRect() for i in range(len(self.pattern.coordinates)): coordinates = self.pattern.coordinates[i] colour_item = self.colourModel.item(i) lines = [] xb, yb = [], [] mx, my = 0, 0 for op, x, y in coordinates: xb.append(x) yb.append(y) if op == "move": mx, my = x, y elif op == "stitch": line = QLine(mx, -my, x, -y) lines.append(line) mx, my = x, y xb = [min(xb), max(xb)] yb = [min(yb), max(yb)] rect = QRect(min(xb), -max(yb), max(xb) - min(xb), max(yb) - min(yb)) self.rect = self.rect.united(rect) zone = Zone(rect, colour_item) zone.lines = lines self._partition_data(zone) self.zones.append(zone)
def paint(self, painter, *args): # NEED *args for WINDOWS! if len(self.layers) == 0 or self.length == -1: return if self.isVertical: h = self.boundingRect().height() - 2 w = self.length line = QLine(w - 1, 0, w - 1, h - 1) else: h = self.boundingRect().height() - self.length w = self.boundingRect().width() - 2 line = QLine(0, h - 1, w - 1, h - 1) image = self.contentImage().copy(0, 0, w, h) painter.drawImage(QRect(0, 0, w, h), image) painter.drawLine(line)
def drawGrid(self, painter, option, index): # grab the rect information left = option.rect.left() right = option.rect.right() top = option.rect.top() bottom = option.rect.bottom() # draw to the root for the first item if (not index.column()): left = 0 lines = [] if (self.showColumns()): # only need to draw the right most line, since items will build together lines.append(QLine(right, top, right, bottom)) if (self.showRows()): # only need to draw the bottom most line, since items will draw together lines.append(QLine(left, bottom, right, bottom)) painter.setPen(self.borderColor()) painter.drawLines(lines)
def paintEvent( self, event ): """ Overloads the paint event to handle drawing the splitter lines. :param event | <QPaintEvent> """ lines = [] count = 20 # calculate the lines if ( self.orientation() == Qt.Vertical ): x = self._resizeGrip.pos().x() h = self.height() spacing = int(float(self._resizeGrip.width()) / count) for i in range(count): lines.append(QLine(x, 0, x, h)) x += spacing else: y = self._resizeGrip.pos().y() w = self.width() spacing = int(float(self._resizeGrip.height()) / count) for i in range(count): lines.append(QLine(0, y, w, y)) y += spacing # draw the lines painter = QPainter() painter.begin(self) pal = self.palette() painter.setPen(pal.color(pal.Window).darker(120)) painter.drawLines(lines) painter.end()
def mouseMoveEvent(self, event): if self._start_sel: if self._sel_accepted or ( event.pos() - self._start_selection ).manhattanLength() >= QApplication.startDragDistance(): scene = self.scene() self._sel_accepted = True event.accept() viewport = self.viewport() viewport.update(self.rubberBandRegion(self._sel_rect)) new_rect = QRect(self._start_selection, event.pos()).normalized() viewport.update(self.rubberBandRegion(new_rect)) self._sel_rect = new_rect scene_poly = self.mapToScene(new_rect) for it in scene.items(): it.setSelected(False) for it in scene.items(scene_poly): it.setSelected(True) return elif self._first_point is not None: if self._div_accepted or ( event.pos() - self._start_selection ).manhattanLength() >= QApplication.startDragDistance(): scene = self.scene() self._div_accepted = True event.accept() viewport = self.viewport() if not self._div_line.isNull(): viewport.update(self.lineSelectionRect(self._div_line)) first_point = self._first_point first_pos = self.mapFromScene(first_point.pos()) new_line = QLine(first_pos, event.pos()) viewport.update(self.lineSelectionRect(new_line)) self._div_line = new_line scene_pos = self.mapToScene(event.pos()) if self._second_point is not None: self._second_point.setSelected(False) self._second_point = None for it in scene.items(scene_pos): if isinstance(it, PointItem ) and it.pt_id in scene.data_manager.cells[ scene.current_cell]: it.setSelected(True) self._second_point = it return QGraphicsView.mouseMoveEvent(self, event)
def _create_line(self): x = self.print_width self.line = QLine(x, 0, x, self.height())
def rebuildDays(self): """ Rebuilds the interface as a week display. """ time = QTime(0, 0, 0) hour = True x = 6 y = 6 + 24 w = self.width() - 12 - 25 dh = 48 indent = 58 text_data = [] vlines = [] hlines = [QLine(x, y, w, y)] time_grids = [] for i in range(48): if (hour): hlines.append(QLine(x, y, w, y)) text_data.append( (x, y + 6, indent - 6, dh, Qt.AlignRight | Qt.AlignTop, time.toString('hap'))) else: hlines.append(QLine(x + indent, y, w, y)) time_grids.append((time, y, dh / 2)) # move onto the next line hour = not hour time = time.addSecs(30 * 60) y += dh / 2 hlines.append(QLine(x, y, w, y)) h = y y = 6 + 24 # load the grid vlines.append(QLine(x, y, x, h)) vlines.append(QLine(x + indent, y, x + indent, h)) vlines.append(QLine(w, y, w, h)) today = QDate.currentDate() curr_date = self.currentDate() # load the days if (self.currentMode() == XCalendarScene.Mode.Week): date = self.currentDate() day_of_week = date.dayOfWeek() if (day_of_week == 7): day_of_week = 0 min_date = date.addDays(-day_of_week) max_date = date.addDays(6 - day_of_week) self._minimumDate = min_date self._maximumDate = max_date dw = (w - (x + indent)) / 7.0 vx = x + indent date = min_date for i in range(7): vlines.append(QLine(vx, y, vx, h)) text_data.append((vx + 6, 6, dw, 24, Qt.AlignCenter, date.toString('ddd MM/dd'))) self._dateGrid[date.toJulianDay()] = ((0, i), QRectF(vx, y, dw, h - y)) # create the date grid for date time options for r, data in enumerate(time_grids): time, ty, th = data dtime = QDateTime(date, time) key = dtime.toTime_t() self._dateTimeGrid[key] = ((r, i), QRectF(vx, ty, dw, th)) if (date == curr_date): self._buildData['curr_date'] = QRectF(vx, y, dw, h - 29) elif (date == today): self._buildData['today'] = QRectF(vx, y, dw, h - 29) date = date.addDays(1) vx += dw # load a single day else: date = self.currentDate() self._maximumDate = date self._minimumDate = date text_data.append((x + indent, 6, w, 24, Qt.AlignCenter, date.toString('ddd MM/dd'))) self._dateGrid[date.toJulianDay()] = ((0, 0), QRectF(x, y, w - x, h - y)) # create the date grid for date time options for r, data in enumerate(time_grids): time, ty, th = data dtime = QDateTime(date, time) key = dtime.toTime_t() rect = QRectF(x + indent, ty, w - (x + indent), th) self._dateTimeGrid[key] = ((r, 0), rect) self._buildData['grid'] = hlines + vlines self._buildData['regular_text'] = text_data rect = self.sceneRect() rect.setHeight(h + 6) super(XCalendarScene, self).setSceneRect(rect)
def paintEvent(self, event): painter = QPainter(self) painter.drawImage( event.rect(), self.image.scaledToWidth(self.width * self.image_pixel_width, Qt.SmoothTransformation)) if self.agc_roi_from != None and self.agc_roi_to != None and not self.image_is_16bit: pen = QPen() pen.setColor(Qt.green) pen.setWidth(1) painter.setPen(pen) roi = self.parent.get_agc_roi() painter.drawRect(roi[0] * self.image_pixel_width + 1, roi[1] * self.image_pixel_width + 1, (roi[2] - roi[0]) * self.image_pixel_width + 1, (roi[3] - roi[1]) * self.image_pixel_width + 1) self.parent.update_agc_roi_label() if self.spotmeter_roi_from != None and self.spotmeter_roi_to != None: pen = QPen() pen.setColor(Qt.white) pen.setWidth(1) painter.setPen(pen) from_x, from_y, to_x, to_y = self.parent.get_spotmeter_roi() from_x = from_x * self.image_pixel_width + 1 from_y = from_y * self.image_pixel_width + 1 to_x = to_x * self.image_pixel_width + 1 to_y = to_y * self.image_pixel_width + 1 cross_x = from_x + (to_x - from_x) / 2.0 cross_y = from_y + (to_y - from_y) / 2.0 if to_x - from_x > 5 or to_y - from_y > 5: lines = [ QLine(from_x, from_y, from_x + self.crosshair_width, from_y), QLine(from_x, from_y, from_x, from_y + self.crosshair_width), QLine(to_x, to_y, to_x, to_y - self.crosshair_width), QLine(to_x, to_y, to_x - self.crosshair_width, to_y), QLine(from_x, to_y, from_x, to_y - self.crosshair_width), QLine(from_x, to_y, from_x + self.crosshair_width, to_y), QLine(to_x, from_y, to_x, from_y + self.crosshair_width), QLine(to_x, from_y, to_x - self.crosshair_width, from_y) ] painter.drawLines(lines) lines = [ QLine(cross_x - self.crosshair_width, cross_y, cross_x + self.crosshair_width, cross_y), QLine(cross_x, cross_y - self.crosshair_width, cross_x, cross_y + self.crosshair_width) ] painter.drawLines(lines) self.parent.update_spotmeter_roi_label()
class TrackingView(QGraphicsView): def __init__(self, *args): QGraphicsView.__init__(self, *args) self._sel_rect = QRect() self._start_selection = None self._start_sel = False self._sel_accepted = False self._first_point = None self._second_point = None self._div_accepted = False self._div_line = QLine() def rubberBandRegion(self, rect): viewport = self.viewport() mask = QStyleHintReturnMask() option = QStyleOptionRubberBand() option.initFrom(viewport) option.rect = rect option.opaque = False option.shape = QRubberBand.Rectangle tmp = QRegion() tmp += rect if viewport.style().styleHint(QStyle.SH_RubberBand_Mask, option, viewport, mask): tmp &= mask.region return tmp def lineSelectionRect(self, line): rect = QRect(line.p1(), line.p2()).normalized() if rect.isValid(): rect.adjust(-2, -2, 2, 2) return rect def mousePressEvent(self, event): scene = self.scene() if not isinstance(scene, TrackingScene): return QGraphicsView.mousePressEvent(self, event) QGraphicsView.mousePressEvent(self, event) if not event.isAccepted(): if scene.mode == TrackingScene.AddCell and event.buttons( ) == Qt.LeftButton: event.accept() self._start_selection = QPoint(event.pos()) if scene.has_current_cell: items = scene.items(self.mapToScene(event.pos())) try: first_point = items[0] if isinstance( first_point, PointItem ) and first_point.pt_id in scene.data_manager.cells[ scene.current_cell]: self._first_point = first_point params = parameters.instance params.is_cell_editable = False return except IndexError: pass self._start_sel = True def mouseMoveEvent(self, event): if self._start_sel: if self._sel_accepted or ( event.pos() - self._start_selection ).manhattanLength() >= QApplication.startDragDistance(): scene = self.scene() self._sel_accepted = True event.accept() viewport = self.viewport() viewport.update(self.rubberBandRegion(self._sel_rect)) new_rect = QRect(self._start_selection, event.pos()).normalized() viewport.update(self.rubberBandRegion(new_rect)) self._sel_rect = new_rect scene_poly = self.mapToScene(new_rect) for it in scene.items(): it.setSelected(False) for it in scene.items(scene_poly): it.setSelected(True) return elif self._first_point is not None: if self._div_accepted or ( event.pos() - self._start_selection ).manhattanLength() >= QApplication.startDragDistance(): scene = self.scene() self._div_accepted = True event.accept() viewport = self.viewport() if not self._div_line.isNull(): viewport.update(self.lineSelectionRect(self._div_line)) first_point = self._first_point first_pos = self.mapFromScene(first_point.pos()) new_line = QLine(first_pos, event.pos()) viewport.update(self.lineSelectionRect(new_line)) self._div_line = new_line scene_pos = self.mapToScene(event.pos()) if self._second_point is not None: self._second_point.setSelected(False) self._second_point = None for it in scene.items(scene_pos): if isinstance(it, PointItem ) and it.pt_id in scene.data_manager.cells[ scene.current_cell]: it.setSelected(True) self._second_point = it return QGraphicsView.mouseMoveEvent(self, event) def mouseReleaseEvent(self, event): if self._start_sel: self._start_sel = False if self._sel_accepted: self.viewport().update(self.rubberBandRegion(self._sel_rect)) sceneRegion = self.mapToScene(self._sel_rect) self._sel_accepted = False self._sel_rect = QRect() event.accept() if self.scene(): self.scene().setPointCellSelection(sceneRegion) return elif self._first_point is not None: scene = self.scene() div_accepted = self._div_accepted if div_accepted: event.accept() self.viewport().update(self.lineSelectionRect(self._div_line)) if self._second_point is not None: scene.setDivisionLine(self._first_point, self._second_point) self._second_point.setSelected(False) self._first_point = None self._second_point = None self._div_line = QLine() self._div_accepted = False params = parameters.instance params.is_cell_editable = True if div_accepted: return QGraphicsView.mouseReleaseEvent(self, event) def drawForeground(self, painter, rect): QGraphicsView.drawForeground(self, painter, rect) if self._sel_accepted: painter.save() painter.resetTransform() rect = self._sel_rect viewport = self.viewport() option = QStyleOptionRubberBand() option.initFrom(viewport) option.rect = self._sel_rect option.shape = QRubberBand.Rectangle mask = QStyleHintReturnMask() self.style().drawControl(QStyle.CE_RubberBand, option, painter, viewport) painter.restore() elif self._div_accepted: painter.save() painter.resetTransform() line = self._div_line viewport = self.viewport() palette = viewport.palette() pen = QPen(Qt.DashDotLine) pen.setWidth(2) pen.setColor(Qt.red) painter.setPen(pen) painter.drawLine(self._div_line) painter.restore()
def paint(self, painter, option, index): painter.save() cell_width = self.size.width() #if option.state & QStyle.State_Selected: # painter.fillRect(option.rect, option.palette.highlight()) #painter.drawRect(option.rect) # Draw marks before translating painter # ===================================== # Draw avatar if not self.avatar: avatar_filepath = index.data(self.AvatarRole).toPyObject() self.avatar = QPixmap(avatar_filepath) x = option.rect.left() + (self.BOX_MARGIN * 2) y = option.rect.top() + (self.BOX_MARGIN * 2) rect = QRect(x, y, self.AVATAR_SIZE, self.AVATAR_SIZE) painter.drawPixmap(rect, self.avatar) # Draw verified account icon if index.data(self.VerifiedRole).toPyObject(): rect2 = QRect(rect.right() - 11, rect.bottom() - 10, 16, 16) painter.drawPixmap(rect2, self.verified_icon) marks_margin = 0 # Favorite mark if index.data(self.FavoritedRole).toPyObject(): x = cell_width - 16 - self.BOX_MARGIN y = option.rect.top() + self.BOX_MARGIN rect = QRect(x, y, 16, 16) painter.drawPixmap(rect, self.favorite_icon) marks_margin = 16 # Draw reposted icon if index.data(self.RepeatedRole).toPyObject(): x = cell_width - 16 - self.BOX_MARGIN - marks_margin y = option.rect.top() + self.BOX_MARGIN rect = QRect(x, y, 16, 16) painter.drawPixmap(rect, self.repeated_icon) # Draw protected account icon protected_icon_margin = 0 if index.data(self.ProtectedRole).toPyObject(): x = option.rect.left( ) + self.BOX_MARGIN + self.AVATAR_SIZE + self.LEFT_MESSAGE_MARGIN y = option.rect.top() + self.BOX_MARGIN rect = QRect(x, y, 16, 16) painter.drawPixmap(rect, self.protected_icon) protected_icon_margin = 16 # ==== End of pixmap drawing ==== accumulated_height = 0 # Draw fullname fullname = self.__render_fullname(cell_width, index) x = option.rect.left() + self.BOX_MARGIN + self.AVATAR_SIZE x += self.LEFT_MESSAGE_MARGIN + protected_icon_margin y = option.rect.top() painter.translate(x, y) fullname.drawContents(painter) # Draw username username = self.__render_username(cell_width, index) painter.translate(fullname.idealWidth(), 0) username.drawContents(painter) # Draw status message x = -fullname.idealWidth() - protected_icon_margin y = fullname.size().height() + self.TOP_MESSAGE_MARGIN painter.translate(x, y) message = self.__render_status_message(cell_width, index) message.drawContents(painter) accumulated_height += y + message.size().height() # Draw reposted by x = self.BOX_MARGIN + 16 - (self.LEFT_MESSAGE_MARGIN + self.AVATAR_SIZE) y = message.size().height() + self.BOTTOM_MESSAGE_MARGIN if accumulated_height < self.AVATAR_SIZE: y += (self.AVATAR_SIZE - accumulated_height) + self.COMPLEMENT_HEIGHT painter.translate(x, y) reposted_by = index.data(self.RepostedRole).toPyObject() if reposted_by: reposted = QTextDocument() reposted.setHtml("<span style='color: #999;'>%s</span>" % reposted_by) reposted.setDefaultFont(FOOTER_FONT) reposted.setTextWidth(self.__calculate_text_width(cell_width)) reposted.drawContents(painter) # Draw reposted icon rect2 = QRect(-16, 3, 16, 16) painter.drawPixmap(rect2, self.reposted_icon) # Draw datetime datetime = index.data(self.DateRole).toPyObject() timestamp = QTextDocument() timestamp.setHtml("<span style='color: #999;'>%s</span>" % datetime) timestamp.setDefaultFont(FOOTER_FONT) timestamp.setTextWidth(self.__calculate_text_width(cell_width)) x = self.size.width() - timestamp.idealWidth() - 20 - self.BOX_MARGIN painter.translate(x, 0) timestamp.drawContents(painter) painter.resetTransform() painter.translate(0, option.rect.bottom()) line = QLine(0, 0, option.rect.width(), 0) painter.setPen(QColor(230, 230, 230)) painter.drawLine(line) painter.restore()
def rebuildMonth(self): """ Rebuilds the month for this scene. """ # make sure we start at 0 for sunday vs. 7 for sunday day_map = dict([(i + 1, i + 1) for i in range(7)]) day_map[7] = 0 today = QDate.currentDate() curr = self.currentDate() first = QDate(curr.year(), curr.month(), 1) last = QDate(curr.year(), curr.month(), curr.daysInMonth()) first = first.addDays(-day_map[first.dayOfWeek()]) last = last.addDays(6 - day_map[last.dayOfWeek()]) cols = 7 rows = (first.daysTo(last) + 1) / cols hlines = [] vlines = [] padx = 6 pady = 6 header = 24 w = self.width() - (2 * padx) h = self.height() - (2 * pady) dw = (w / cols) - 1 dh = ((h - header) / rows) - 1 x0 = padx y0 = pady + header x = x0 y = y0 for row in range(rows + 1): hlines.append(QLine(x0, y, w, y)) y += dh for col in range(cols + 1): vlines.append(QLine(x, y0, x, h)) x += dw self._buildData['grid'] = hlines + vlines # draw the date fields date = first row = 0 col = 0 # draw the headers x = x0 y = pady regular_text = [] mid_text = [] self._buildData['regular_text'] = regular_text self._buildData['mid_text'] = mid_text for day in ('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'): regular_text.append( (x + 5, y, dw, y0, Qt.AlignLeft | Qt.AlignVCenter, day)) x += dw for i in range(first.daysTo(last) + 1): top = (y0 + (row * dh)) left = (x0 + (col * dw)) rect = QRectF(left - 1, top, dw, dh) # mark the current date on the calendar if (date == curr): self._buildData['curr_date'] = rect # mark today's date on the calendar elif (date == today): self._buildData['today'] = rect # determine how to draw the calendar format = 'd' if (date.day() == 1): format = 'MMM d' # determine the color to draw the text if (date.month() == curr.month()): text = regular_text else: text = mid_text # draw the text text.append( (left + 2, top + 2, dw - 4, dh - 4, Qt.AlignTop | Qt.AlignLeft, date.toString(format))) # update the limits if (not i): self._minimumDate = date self._maximumDate = date self._dateGrid[date.toJulianDay()] = ((row, col), rect) if (col == (cols - 1)): row += 1 col = 0 else: col += 1 date = date.addDays(1)
def updateAxisLines(self, yTop, yBottom): """The window has been resized, we need to update the lines""" self.lines = [QLine(self.x, yTop, self.x, yBottom)] return
class TrackingView(QGraphicsView): def __init__(self, *args): QGraphicsView.__init__(self, *args) self._sel_rect = QRect() self._start_selection = None self._start_sel = False self._sel_accepted = False self._first_point = None self._second_point = None self._div_accepted = False self._div_line = QLine() def rubberBandRegion(self, rect): viewport = self.viewport() mask = QStyleHintReturnMask() option = QStyleOptionRubberBand() option.initFrom(viewport) option.rect = rect option.opaque = False option.shape = QRubberBand.Rectangle tmp = QRegion() tmp += rect if viewport.style().styleHint(QStyle.SH_RubberBand_Mask, option, viewport, mask): tmp &= mask.region return tmp def lineSelectionRect(self, line): rect = QRect(line.p1(), line.p2()).normalized() if rect.isValid(): rect.adjust(-2, -2, 2, 2) return rect def mousePressEvent(self, event): scene = self.scene() if not isinstance(scene, TrackingScene): return QGraphicsView.mousePressEvent(self, event) QGraphicsView.mousePressEvent(self, event) if not event.isAccepted(): if scene.mode == TrackingScene.AddCell and event.buttons() == Qt.LeftButton: event.accept() self._start_selection = QPoint(event.pos()) if scene.has_current_cell: items = scene.items(self.mapToScene(event.pos())) try: first_point = items[0] if isinstance(first_point, PointItem) and first_point.pt_id in scene.data_manager.cells[scene.current_cell]: self._first_point = first_point params = parameters.instance params.is_cell_editable = False return except IndexError: pass self._start_sel = True def mouseMoveEvent(self, event): if self._start_sel: if self._sel_accepted or (event.pos() - self._start_selection).manhattanLength() >= QApplication.startDragDistance(): scene = self.scene() self._sel_accepted = True event.accept() viewport = self.viewport() viewport.update(self.rubberBandRegion(self._sel_rect)) new_rect = QRect(self._start_selection, event.pos()).normalized() viewport.update(self.rubberBandRegion(new_rect)) self._sel_rect = new_rect scene_poly = self.mapToScene(new_rect) for it in scene.items(): it.setSelected(False) for it in scene.items(scene_poly): it.setSelected(True) return elif self._first_point is not None: if self._div_accepted or (event.pos() - self._start_selection).manhattanLength() >= QApplication.startDragDistance(): scene = self.scene() self._div_accepted = True event.accept() viewport = self.viewport() if not self._div_line.isNull(): viewport.update(self.lineSelectionRect(self._div_line)) first_point = self._first_point first_pos = self.mapFromScene(first_point.pos()) new_line = QLine(first_pos, event.pos()) viewport.update(self.lineSelectionRect(new_line)) self._div_line = new_line scene_pos = self.mapToScene(event.pos()) if self._second_point is not None: self._second_point.setSelected(False) self._second_point = None for it in scene.items(scene_pos): if isinstance(it, PointItem) and it.pt_id in scene.data_manager.cells[scene.current_cell]: it.setSelected(True) self._second_point = it return QGraphicsView.mouseMoveEvent(self, event) def mouseReleaseEvent(self, event): if self._start_sel: self._start_sel = False if self._sel_accepted: self.viewport().update(self.rubberBandRegion(self._sel_rect)) sceneRegion = self.mapToScene(self._sel_rect) self._sel_accepted = False self._sel_rect = QRect() event.accept() if self.scene(): self.scene().setPointCellSelection(sceneRegion) return elif self._first_point is not None: scene = self.scene() div_accepted = self._div_accepted if div_accepted: event.accept() self.viewport().update(self.lineSelectionRect(self._div_line)) if self._second_point is not None: scene.setDivisionLine(self._first_point, self._second_point) self._second_point.setSelected(False) self._first_point = None self._second_point = None self._div_line = QLine() self._div_accepted = False params = parameters.instance params.is_cell_editable = True if div_accepted: return QGraphicsView.mouseReleaseEvent(self, event) def drawForeground(self, painter, rect): QGraphicsView.drawForeground(self, painter, rect) if self._sel_accepted: painter.save() painter.resetTransform() rect = self._sel_rect viewport = self.viewport() option = QStyleOptionRubberBand() option.initFrom(viewport) option.rect = self._sel_rect option.shape = QRubberBand.Rectangle mask = QStyleHintReturnMask() self.style().drawControl(QStyle.CE_RubberBand, option, painter, viewport); painter.restore() elif self._div_accepted: painter.save() painter.resetTransform() line = self._div_line viewport = self.viewport() palette = viewport.palette() pen = QPen(Qt.DashDotLine) pen.setWidth(2) pen.setColor(Qt.red) painter.setPen(pen) painter.drawLine(self._div_line) painter.restore()
def rebuild(self): """ Rebuilds the scene based on the current settings. :param start | <QDate> end | <QDate> """ gantt = self.ganttWidget() start = gantt.dateStart() end = gantt.dateEnd() cell_width = gantt.cellWidth() cell_height = gantt.cellHeight() rect = self.sceneRect() view = gantt.viewWidget() height = rect.height() header = gantt.treeWidget().header() header_height = header.height() if (not header.isVisible()): header_height = 0 self._labels = [] self._hlines = [] self._vlines = [] self._weekendRects = [] self._bookedRects = [] self._unavailableRects = [] self._overbookedRects = [] self._underbookedRects = [] self._unassignedRects = [] self._holidayRects = [] self._currentDayRects = [] self._alternateRects = [] self._topLabels = [] # generate formatting info top_format = 'MMM' Week = 'd' label_format = 'd' increment = 1 # days # generate vertical lines x = 0 i = 0 half = header_height / 2.0 curr = start top_label = start.toString(top_format) top_rect = QRect(0, 0, 0, half) alt_rect = None while (curr < end): # update the month rect new_top_label = curr.toString(top_format) if (new_top_label != top_label): top_rect.setRight(x) self._topLabels.append((top_rect, top_label)) top_rect = QRect(x, 0, 0, half) top_label = new_top_label if (alt_rect is not None): alt_rect.setRight(x) self._alternateRects.append(alt_rect) alt_rect = None else: alt_rect = QRect(x, 0, 0, height) # create the line self._hlines.append(QLine(x, 0, x, height)) # create the header label/rect label = str(curr.toString(label_format)) rect = QRect(x, half, cell_width, half) self._labels.append((rect, label)) # store weekend rectangles if (curr.dayOfWeek() in (6, 7)): rect = QRect(x, 0, cell_width, height) self._weekendRects.append(rect) # store current day rectangle elif (curr.toString("ddMMyyyy") == QDate.currentDate().toString( "ddMMyyyy")): rect = QRect(x, 0, cell_width, height) self._currentDayRects.append(rect) # store holiday rectangles # increment the dates curr = curr.addDays(increment) x += cell_width i += 1 self._maxOverbooked = 0 if gantt._availabilityEnabled: #iterate through rows for itemcount in range(0, gantt.topLevelItemCount()): #check top item, then check child items item = gantt.topLevelItem(itemcount) if item._dbEntry is not None: if item._dbEntry._type == "phase": phase = item._dbEntry for key in phase._availability.keys(): if QDate.fromString(key, "yyyy-MM-dd") >= start: diff = start.daysTo( QDate.fromString(key, "yyyy-MM-dd")) rect = QRect( (diff) * cell_width, header_height + cell_height * (itemcount), cell_width, cell_height) if phase._availability[key] == 1: self._underbookedRects.append(rect) elif phase._availability[key] == 2: self._bookedRects.append(rect) elif phase._availability[key] > 2: if self._maxOverbooked < int( phase._availability[key]): self._maxOverbooked = int( phase._availability[key]) self._overbookedRects.append( [rect, int(phase._availability[key])]) ''' for pa in item._dbEntry._phaseAssignments.values(): for key in pa._availability.keys(): if pa._availability[key] > 8: if QDate.fromString(key,"yyyy-MM-dd") >= start: diff = start.daysTo(QDate.fromString(key,"yyyy-MM-dd")) rect = QRect((diff)*cell_width, header_height+cell_height*(itemcount), cell_width, cell_height) self._overbookedRects.append(rect) ''' # update the month rect top_rect.setRight(x) top_label = end.toString(top_format) self._topLabels.append((top_rect, top_label)) if (alt_rect is not None): alt_rect.setRight(x) self._alternateRects.append(alt_rect) # resize the width to match the last date range new_width = x self.setSceneRect(0, 0, new_width, height) # generate horizontal lines y = 0 h = height width = new_width while (y < h): self._vlines.append(QLine(0, y, width, y)) y += cell_height # clear the dirty flag self._dirty = False
def paintEvent(self, event): option = QStyleOption() option.initFrom(self) contents_rect = self.style().subElementRect(QStyle.SE_FrameContents, option, self) or self.contentsRect() # the SE_FrameContents rect is Null unless the stylesheet defines decorations if self.graphStyle == self.BarStyle: graph_width = self.__dict__['graph_width'] = int(ceil(float(contents_rect.width()) / self.horizontalPixelsPerUnit)) else: graph_width = self.__dict__['graph_width'] = int(ceil(float(contents_rect.width() - 1) / self.horizontalPixelsPerUnit) + 1) max_value = self.__dict__['max_value'] = max(chain([0], *(islice(reversed(graph.data), graph_width) for graph in self.graphs if graph.enabled))) if self.graphHeight == self.AutomaticHeight or self.graphHeight < 0: graph_height = self.__dict__['graph_height'] = max(self.scaler.get_height(max_value), self.minHeight) else: graph_height = self.__dict__['graph_height'] = max(self.graphHeight, self.minHeight) if self.graphStyle == self.BarStyle: height_scaling = float(contents_rect.height()) / graph_height else: height_scaling = float(contents_rect.height() - self.lineThickness) / graph_height painter = QStylePainter(self) painter.drawPrimitive(QStyle.PE_Widget, option) painter.setClipRect(contents_rect) painter.save() painter.translate(contents_rect.x() + contents_rect.width() - 1, contents_rect.y() + contents_rect.height() - 1) painter.scale(-1, -1) painter.setRenderHint(QStylePainter.Antialiasing, self.graphStyle != self.BarStyle) for graph in (graph for graph in self.graphs if graph.enabled and graph.data): if self.boundary is not None and 0 < self.boundary < graph_height: boundary_width = min(5.0/height_scaling, self.boundary-0, graph_height-self.boundary) pen_color = QLinearGradient(0, (self.boundary - boundary_width) * height_scaling, 0, (self.boundary + boundary_width) * height_scaling) pen_color.setColorAt(0, graph.color) pen_color.setColorAt(1, graph.over_boundary_color) brush_color = QLinearGradient(0, (self.boundary - boundary_width) * height_scaling, 0, (self.boundary + boundary_width) * height_scaling) brush_color.setColorAt(0, self.color_with_alpha(graph.color, self.fillTransparency)) brush_color.setColorAt(1, self.color_with_alpha(graph.over_boundary_color, self.fillTransparency)) else: pen_color = graph.color brush_color = self.color_with_alpha(graph.color, self.fillTransparency) dataset = islice(reversed(graph.data), graph_width) if self.graphStyle == self.BarStyle: lines = [QLine(x*self.horizontalPixelsPerUnit, 0, x*self.horizontalPixelsPerUnit, y*height_scaling) for x, y in enumerate(dataset)] painter.setPen(QPen(pen_color, self.lineThickness)) painter.drawLines(lines) else: painter.translate(0, +self.lineThickness/2 - 1) if self.smoothEnvelope and self.smoothFactor > 0: min_value = 0 max_value = graph_height * height_scaling cx_offset = self.horizontalPixelsPerUnit / 3.0 smoothness = self.smoothFactor last_values = deque(3*[dataset.next() * height_scaling], maxlen=3) # last 3 values: 0 last, 1 previous, 2 previous previous envelope = QPainterPath() envelope.moveTo(0, last_values[0]) for x, y in enumerate(dataset, 1): x = x * self.horizontalPixelsPerUnit y = y * height_scaling * (1 - smoothness) + last_values[0] * smoothness last_values.appendleft(y) c1x = x - cx_offset * 2 c2x = x - cx_offset c1y = limit((1 + smoothness) * last_values[1] - smoothness * last_values[2], min_value, max_value) # same gradient as previous previous value to previous value c2y = limit((1 - smoothness) * last_values[0] + smoothness * last_values[1], min_value, max_value) # same gradient as previous value to last value envelope.cubicTo(c1x, c1y, c2x, c2y, x, y) else: envelope = QPainterPath() envelope.addPolygon(QPolygonF([QPointF(x*self.horizontalPixelsPerUnit, y*height_scaling) for x, y in enumerate(dataset)])) if self.fillEnvelope or graph.fill_envelope: first_element = envelope.elementAt(0) last_element = envelope.elementAt(envelope.elementCount() - 1) fill_path = QPainterPath() fill_path.moveTo(last_element.x, last_element.y) fill_path.lineTo(last_element.x + 1, last_element.y) fill_path.lineTo(last_element.x + 1, -self.lineThickness) fill_path.lineTo(-self.lineThickness, -self.lineThickness) fill_path.lineTo(-self.lineThickness, first_element.y) fill_path.connectPath(envelope) painter.fillPath(fill_path, brush_color) painter.strokePath(envelope, QPen(pen_color, self.lineThickness, join=Qt.RoundJoin)) painter.translate(0, -self.lineThickness/2 + 1) if self.boundary is not None and self.boundaryColor: painter.setRenderHint(QStylePainter.Antialiasing, False) painter.setPen(QPen(self.boundaryColor, 1.0)) painter.drawLine(0, self.boundary*height_scaling, contents_rect.width(), self.boundary*height_scaling) painter.restore() # queue the 'updated' signal to be emited after returning to the main loop QMetaObject.invokeMethod(self, 'updated', Qt.QueuedConnection)