def drawBackgroundToPixmap(self): r = self.sceneRect() self.background = QPixmap(qRound(r.width()), qRound(r.height())) self.background.fill(Qt.black) painter = QPainter(self.background) bg = QImage("%simg/BG.png" % (colors.SYSPATH)) painter.drawImage(0, 0, bg)
def paint(self, painter, option=None, widget=None): if self._validateImage(): wasSmoothPixmapTransform = painter.testRenderHint( QPainter.SmoothPixmapTransform) painter.setRenderHint(QPainter.SmoothPixmapTransform) if Colors.noRescale: # Let the painter scale the image for us. This may degrade # both quality and performance. if self._sharedImage.image is not None: painter.drawImage(self.pos(), self._sharedImage.image) else: painter.drawPixmap(self.pos(), self._sharedImage.pixmap) else: m = painter.worldTransform() painter.setWorldTransform(QTransform()) x = m.dx() y = m.dy() if self.noSubPixeling: x = qRound(x) y = qRound(y) if self._sharedImage.image is not None: painter.drawImage(QPointF(x, y), self._sharedImage.image) else: painter.drawPixmap(QPointF(x, y), self._sharedImage.pixmap) if not wasSmoothPixmapTransform: painter.setRenderHint(QPainter.SmoothPixmapTransform, False)
def paint(self, painter, option=None, widget=None): if self._validateImage(): wasSmoothPixmapTransform = painter.testRenderHint(QPainter.SmoothPixmapTransform) painter.setRenderHint(QPainter.SmoothPixmapTransform) if Colors.noRescale: # Let the painter scale the image for us. This may degrade # both quality and performance. if self._sharedImage.image is not None: painter.drawImage(self.pos(), self._sharedImage.image) else: painter.drawPixmap(self.pos(), self._sharedImage.pixmap) else: m = painter.worldTransform() painter.setWorldTransform(QTransform()) x = m.dx() y = m.dy() if self.noSubPixeling: x = qRound(x) y = qRound(y) if self._sharedImage.image is not None: painter.drawImage(QPointF(x, y), self._sharedImage.image) else: painter.drawPixmap(QPointF(x, y), self._sharedImage.pixmap) if not wasSmoothPixmapTransform: painter.setRenderHint(QPainter.SmoothPixmapTransform, False)
def drawBackgroundToPixmap(self): r = self.scene.sceneRect() self.background = QPixmap(qRound(r.width()), qRound(r.height())) self.background.fill(Qt.black) painter = QPainter(self.background) bg = QImage(':/images/demobg.png') painter.drawImage(0, 0, bg)
def drawScaleContents( self, painter, double ): dir = 360 - qRound( self.origin() - self.value() ) # counter clockwise arc = 90 + qRound( self.gradient() * 90 ) skyColor = QColor( 38, 151, 221 ) painter.save() painter.setBrush( skyColor ) painter.drawChord( self.scaleInnerRect(), ( dir - arc ) * 16, 2 * arc * 16 ) painter.restore()
def lineNumberAreaPaintEvent(self, event): painter = QPainter(self.lineNumberArea) painter.fillRect(event.rect(), QColor(69, 69, 69)) block = self.firstVisibleBlock() blockNumber = block.blockNumber() top = qRound(self.blockBoundingGeometry(block).translated(self.contentOffset()).top()) bottom = top + qRound(self.blockBoundingRect(block).height()) while block.isValid() and top <= event.rect().bottom(): if block.isVisible() and bottom >= event.rect().top(): number = str(blockNumber + 1) painter.setPen(QColor(170, 170, 170)) painter.drawText(0, top, self.lineNumberArea.width(), self.fontMetrics().height(), Qt.AlignRight, number + " ") block = block.next() top = bottom bottom = top + qRound(self.blockBoundingRect(block).height()) blockNumber += 1
def _paint_icon(self, iconic, painter, rect, mode, state, options): """Paint a single icon.""" painter.save() color = options['color'] char = options['char'] color_options = { QIcon.On: { QIcon.Normal: (options['color_on'], options['on']), QIcon.Disabled: (options['color_on_disabled'], options['on_disabled']), QIcon.Active: (options['color_on_active'], options['on_active']), QIcon.Selected: (options['color_on_selected'], options['on_selected']) }, QIcon.Off: { QIcon.Normal: (options['color_off'], options['off']), QIcon.Disabled: (options['color_off_disabled'], options['off_disabled']), QIcon.Active: (options['color_off_active'], options['off_active']), QIcon.Selected: (options['color_off_selected'], options['off_selected']) } } color, char = color_options[state][mode] painter.setPen(QColor(color)) # A 16 pixel-high icon yields a font size of 14, which is pixel perfect # for font-awesome. 16 * 0.875 = 14 # The reason why the glyph size is smaller than the icon size is to # account for font bearing. draw_size = 0.875 * qRound(rect.height() * options['scale_factor']) prefix = options['prefix'] # Animation setup hook animation = options.get('animation') if animation is not None: animation.setup(self, painter, rect) painter.setFont(iconic.font(prefix, draw_size)) if 'offset' in options: rect = QRect(rect) rect.translate(options['offset'][0] * rect.width(), options['offset'][1] * rect.height()) painter.setOpacity(options.get('opacity', 1.0)) painter.drawText(rect, Qt.AlignCenter | Qt.AlignVCenter, char) painter.restore()
def statusAreaPaintEvent(self, event: QPaintEvent): painter = QPainter(self._statusArea) painter.fillRect(event.rect(), Qt.lightGray) block = self.firstVisibleBlock() top = qRound( self.blockBoundingGeometry(block).translated( self.contentOffset()).top()) bottom = top + qRound(self.blockBoundingRect(block).height()) while block.isValid() and top <= event.rect().bottom(): if block.isVisible() and bottom >= event.rect().top(): painter.setPen(Qt.red) painter.drawText( 0, top, self._statusArea.width(), self.fontMetrics().height(), Qt.AlignRight, MARK if block.userState() == self._State.Error else NOMARK, ) block = block.next() top = bottom bottom = top + qRound(self.blockBoundingRect(block).height())
def _paint_icon(self, iconic, painter, rect, mode, state, options): """Paint a single icon""" painter.save() color, char = options['color'], options['char'] if mode == QIcon.Disabled: color = options.get('color_disabled', color) char = options.get('disabled', char) elif mode == QIcon.Active: color = options.get('color_active', color) char = options.get('active', char) elif mode == QIcon.Selected: color = options.get('color_selected', color) char = options.get('selected', char) painter.setPen(QColor(color)) # A 16 pixel-high icon yields a font size of 14, which is pixel perfect # for font-awesome. 16 * 0.875 = 14 # The reason for not using full-sized glyphs is the negative bearing of # fonts. draw_size = 0.875 * qRound(rect.height() * options['scale_factor']) prefix = options['prefix'] # Animation setup hook animation = options.get('animation') if animation is not None: animation.setup(self, painter, rect) painter.setFont(iconic.font(prefix, draw_size)) if 'offset' in options: rect = QRect(rect) rect.translate(options['offset'][0] * rect.width(), options['offset'][1] * rect.height()) painter.setOpacity(options.get('opacity', 1.0)) painter.drawText(rect, Qt.AlignCenter | Qt.AlignVCenter, char) painter.restore()
def deliverEvent(self, event, texCoord): # Map the texture co-ordinate into "screen" co-ordinates. # Mouse move and release events can extend beyond the boundaries # of the scene, for "click and drag off-screen" operations. # Mouse press and double-click events need to be constrained. bounds = self.sceneRect() screenX = qRound(texCoord.x() * bounds.width()) screenY = qRound((1.0 - texCoord.y()) * bounds.height()) if event.type() in (QEvent.GraphicsSceneMousePress, QEvent.GraphicsSceneMouseDoubleClick, QEvent.MouseButtonPress, QEvent.MouseButtonDblClick): if screenX < 0: screenX = 0 elif screenX >= bounds.width(): screenX = qRound(bounds.width() - 1) if screenY < 0: screenY = 0 elif screenY >= bounds.height(): screenY = qRound(bounds.height() - 1) self.pressedPos = QPoint(screenX, screenY) # Convert the event and deliver it to the scene. eventType = event.type() if eventType in (QEvent.GraphicsSceneMouseMove, QEvent.GraphicsSceneMousePress, QEvent.GraphicsSceneMouseRelease, QEvent.GraphicsSceneMouseDoubleClick): pass #QGraphicsSceneMouseEvent *ev = #static_cast<QGraphicsSceneMouseEvent *>(event) #QGraphicsSceneMouseEvent e(ev->type()) #e.setPos(QPointF(screenX, screenY)) #e.setScenePos(QPointF(screenX + bounds.x(), screenY + bounds.y())) #e.setScreenPos(QPoint(screenX, screenY)) #e.setButtonDownScreenPos(ev->button(), d->pressedPos) #e.setButtonDownScenePos #(ev->button(), QPointF(d->pressedPos.x() + bounds.x(), #d->pressedPos.y() + bounds.y())) #e.setButtons(ev->buttons()) #e.setButton(ev->button()) #e.setModifiers(ev->modifiers()) #e.setAccepted(false) #QApplication::sendEvent(this, &e) elif eventType == QEvent.GraphicsSceneWheel: pass #QGraphicsSceneWheelEvent *ev = #static_cast<QGraphicsSceneWheelEvent *>(event) #QGraphicsSceneWheelEvent e(QEvent::GraphicsSceneWheel) #e.setPos(QPointF(screenX, screenY)) #e.setScenePos(QPointF(screenX + bounds.x(), screenY + bounds.y())) #e.setScreenPos(QPoint(screenX, screenY)) #e.setButtons(ev->buttons()) #e.setModifiers(ev->modifiers()) #e.setDelta(ev->delta()) #e.setOrientation(ev->orientation()) #e.setAccepted(false) #QApplication::sendEvent(this, &e) elif eventType in (QEvent.MouseButtonPress, QEvent.MouseButtonRelease, QEvent.MouseButtonDblClick, QEvent.MouseMove): pass #QMouseEvent *ev = static_cast<QMouseEvent *>(event) #QEvent::Type type #if (ev->type() == QEvent::MouseButtonPress) #type = QEvent::GraphicsSceneMousePress #else if (ev->type() == QEvent::MouseButtonRelease) #type = QEvent::GraphicsSceneMouseRelease #else if (ev->type() == QEvent::MouseButtonDblClick) #type = QEvent::GraphicsSceneMouseDoubleClick #else #type = QEvent::GraphicsSceneMouseMove #QGraphicsSceneMouseEvent e(type) #e.setPos(QPointF(screenX, screenY)) #e.setScenePos(QPointF(screenX + bounds.x(), screenY + bounds.y())) #e.setScreenPos(QPoint(screenX, screenY)) #e.setButtonDownScreenPos(ev->button(), d->pressedPos) #e.setButtonDownScenePos #(ev->button(), QPointF(d->pressedPos.x() + bounds.x(), #d->pressedPos.y() + bounds.y())) #e.setButtons(ev->buttons()) #e.setButton(ev->button()) #e.setModifiers(ev->modifiers()) #e.setAccepted(false) #QApplication::sendEvent(this, &e) elif eventType == QEvent.Wheel: pass #QWheelEvent *ev = static_cast<QWheelEvent *>(event) #QGraphicsSceneWheelEvent e(QEvent::GraphicsSceneWheel) #e.setPos(QPointF(screenX, screenY)) #e.setScenePos(QPointF(screenX + bounds.x(), screenY + bounds.y())) #e.setScreenPos(QPoint(screenX, screenY)) #e.setButtons(ev->buttons()) #e.setModifiers(ev->modifiers()) #e.setDelta(ev->delta()) #e.setOrientation(ev->orientation()) #e.setAccepted(false) #QApplication::sendEvent(this, &e) #else: # Send the event directly without any conversion. # Typically used for keyboard, focus, and enter/leave events. #QApplication.sendEvent(self, event) QApplication.sendEvent(self, event)
def volume(self): linear_volume = QAudio.convertVolume(self.volume_slider.value() / 100, QAudio.LogarithmicVolumeScale, QAudio.LinearVolumeScale) return qRound(linear_volume * 100)
def drawAICompassDisk(self, painter, area, halfspan): start = self.yaw - halfspan end = self.yaw + halfspan firstTick = math.ceil( start / self.COMPASS_DISK_RESOLUTION) * self.COMPASS_DISK_RESOLUTION lastTick = math.floor( end / self.COMPASS_DISK_RESOLUTION) * self.COMPASS_DISK_RESOLUTION radius = area.width() / 2 innerRadius = radius * 0.96 painter.resetTransform() painter.setBrush(self.instrumentBackground) painter.setPen(self.instrumentEdgePen) painter.drawEllipse(area) painter.setBrush(Qt.NoBrush) scalePen = QPen(Qt.black) scalePen.setWidthF(self.fineLineWidth) tickYaw = firstTick while tickYaw <= lastTick: displayTick = tickYaw if displayTick < 0: displayTick += 360 elif displayTick >= 360: displayTick -= 360 # yaw is in center. off = tickYaw - self.yaw # wrap that to ]-180..180] if off <= -180: off += 360 elif off > 180: off -= 360 painter.translate(area.center()) painter.rotate(off) drewArrow = False isMajor = displayTick % self.COMPASS_DISK_MAJORTICK == 0 if displayTick == 30 or displayTick == 60 or \ displayTick ==120 or displayTick ==150 or \ displayTick ==210 or displayTick ==240 or \ displayTick ==300 or displayTick ==330: # draw a number painter.setPen(scalePen) self.drawTextCenter(painter, '{0}'.format(int(displayTick / 10)), self.smallTestSize, 0, -innerRadius * 0.75) else: if displayTick % self.COMPASS_DISK_ARROWTICK == 0: if displayTick != 0: markerPath = QPainterPath( QPointF( 0, -innerRadius * (1 - self.COMPASS_DISK_MARKERHEIGHT / 2))) markerPath.lineTo( innerRadius * self.COMPASS_DISK_MARKERWIDTH / 4, -innerRadius) markerPath.lineTo( -innerRadius * self.COMPASS_DISK_MARKERWIDTH / 4, -innerRadius) markerPath.closeSubpath() painter.setPen(scalePen) painter.setBrush(Qt.SolidPattern) painter.drawPath(markerPath) painter.setBrush(Qt.NoBrush) drewArrow = True if displayTick % 90 == 0: # Also draw a label name = self.compassWindNames[qRound(displayTick / 45)] painter.setPen(scalePen) self.drawTextCenter(painter, name, self.mediumTextSize, 0, -innerRadius * 0.75) # draw the scale lines. If an arrow was drawn, stay off from it. if drewArrow: p_start = QPoint(0, -innerRadius * 0.94) else: p_start = QPoint(0, -innerRadius) if isMajor: p_end = QPoint(0, -innerRadius * 0.86) else: p_end = QPoint(0, -innerRadius * 0.90) painter.setPen(scalePen) painter.drawLine(p_start, p_end) painter.resetTransform() tickYaw += self.COMPASS_DISK_RESOLUTION painter.setPen(scalePen) painter.translate(area.center()) markerPath = QPainterPath(QPointF(0, -radius - 2)) markerPath.lineTo( radius * self.COMPASS_DISK_MARKERWIDTH / 2, -radius - radius * self.COMPASS_DISK_MARKERHEIGHT - 2) markerPath.lineTo( -radius * self.COMPASS_DISK_MARKERWIDTH / 2, -radius - radius * self.COMPASS_DISK_MARKERHEIGHT - 2) markerPath.closeSubpath() painter.drawPath(markerPath) digitalCompassYCenter = -radius * 0.52 digitalCompassHeight = radius * 0.28 digitalCompassBottom = QPointF( 0, digitalCompassYCenter + digitalCompassHeight) digitalCompassAbsoluteBottom = painter.transform().map( digitalCompassBottom) digitalCompassUpshift = 0 if digitalCompassAbsoluteBottom.y() > self.height(): digitalCompassUpshift = digitalCompassAbsoluteBottom.y( ) - self.height() digitalCompassRect = QRectF(-radius / 3, -radius * 0.52 - digitalCompassUpshift, radius * 2 / 3, radius * 0.28) painter.setPen(self.instrumentEdgePen) painter.drawRoundedRect(digitalCompassRect, self.instrumentEdgePen.widthF() * 2 / 3, self.instrumentEdgePen.widthF() * 2 / 3) # final safeguard for really stupid systems digitalCompassValue = qRound(self.yaw) % 360 pen = QPen() pen.setWidthF(self.lineWidth) pen.setColor(Qt.white) painter.setPen(pen) self.drawTextCenter(painter, '%03d' % digitalCompassValue, self.largeTextSize, 0, -radius * 0.38 - digitalCompassUpshift) # The CDI if self.shouldDisplayNavigationData( ) and self.navigationTargetBearing != self.UNKNOWN_ATTITUDE and not math.isinf( self.navigationCrosstrackError): painter.resetTransform() painter.translate(area.center()) # TODO : Sign might be wrong? # TODO : The case where error exceeds max. Truncate to max. and make that visible somehow. # bool errorBeyondRadius = false if abs(self.navigationCrosstrackError) > self.CROSSTRACK_MAX: #errorBeyondRadius = true if self.navigationCrosstrackError > 0: self.navigationCrosstrackError = self.CROSSTRACK_MAX else: self.navigationCrosstrackError = -self.CROSSTRACK_MAX r = radius * self.CROSSTRACK_RADIUS x = self.navigationCrosstrackError / self.CROSSTRACK_MAX * r y = math.sqrt(r * r - x * x) # the positive y, there is also a negative. sillyHeading = 0 angle = sillyHeading - self.navigationTargetBearing # TODO: sign. painter.rotate(-angle) pen = QPen() pen.setWidthF(self.lineWidth) pen.setColor(Qt.black) painter.setPen(pen) painter.drawLine(QPointF(x, y), QPointF(x, -y))
def drawPitchScale(self, painter, area, intrusion, drawNumbersLeft, drawNumbersRight): unused(intrusion) # The area should be quadratic but if not width is the major size. w = area.width() if w < area.height(): w = area.height() pen = QPen() pen.setWidthF(self.lineWidth) pen.setColor(Qt.white) painter.setPen(pen) savedTransform = painter.transform() # find the mark nearest center snap = qRound( self.pitch / self.PITCH_SCALE_RESOLUTION) * self.PITCH_SCALE_RESOLUTION _min = snap - self.PITCH_SCALE_HALFRANGE _max = snap + self.PITCH_SCALE_HALFRANGE degrees = _min while degrees <= _max: isMajor = degrees % (self.PITCH_SCALE_RESOLUTION * 2) == 0 linewidth = self.PITCH_SCALE_MINORWIDTH if isMajor: linewidth = self.PITCH_SCALE_MAJORWIDTH if abs(degrees) > self.PITCH_SCALE_WIDTHREDUCTION_FROM: # we want: 1 at PITCH_SCALE_WIDTHREDUCTION_FROM and PITCH_SCALE_WIDTHREDUCTION at 90. # That is PITCH_SCALE_WIDTHREDUCTION + (1-PITCH_SCALE_WIDTHREDUCTION) * f(pitch) # where f(90)=0 and f(PITCH_SCALE_WIDTHREDUCTION_FROM)=1 # f(p) = (90-p) * 1/(90-PITCH_SCALE_WIDTHREDUCTION_FROM) # or PITCH_SCALE_WIDTHREDUCTION + f(pitch) - f(pitch) * PITCH_SCALE_WIDTHREDUCTION # or PITCH_SCALE_WIDTHREDUCTION (1-f(pitch)) + f(pitch) fromVertical = -90 - self.pitch if self.pitch >= 0: fromVertical = 90 - self.pitch if fromVertical < 0: fromVertical = -fromVertical temp = fromVertical * 1 / ( 90.0 - self.PITCH_SCALE_WIDTHREDUCTION_FROM) linewidth *= (self.PITCH_SCALE_WIDTHREDUCTION * (1 - temp) + temp) shift = self.pitchAngleToTranslation(w, self.pitch - degrees) # TODO: Intrusion detection and evasion. That is, don't draw # where the compass has intruded. painter.translate(0, shift) start = QPointF(-linewidth * w, 0) end = QPointF(linewidth * w, 0) painter.drawLine(start, end) if isMajor and (drawNumbersLeft or drawNumbersRight): displayDegrees = degrees if displayDegrees > 90: displayDegrees = 180 - displayDegrees elif displayDegrees < -90: displayDegrees = -180 - displayDegrees if self.SHOW_ZERO_ON_SCALES or degrees: if drawNumbersLeft: self.drawTextRightCenter( painter, '{0}'.format(displayDegrees), self.mediumTextSize, -self.PITCH_SCALE_MAJORWIDTH * w - 10, 0) if drawNumbersRight: self.drawTextLeftCenter( painter, '{0}'.format(displayDegrees), self.mediumTextSize, self.PITCH_SCALE_MAJORWIDTH * w + 10, 0) painter.setTransform(savedTransform) degrees += self.PITCH_SCALE_RESOLUTION