Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # This Python file uses the following encoding: utf-8
- from PySide6.QtWidgets import QApplication, QLabel, QWidget, QGridLayout, QHBoxLayout, QVBoxLayout, QSpinBox, QSizePolicy, QStackedLayout
- from PySide6.QtGui import QPen, QPainter, QColor, QFont, QRadialGradient, QPolygon, QPaintEvent, QConicalGradient, QGradient, QBrush, QRegion, QResizeEvent
- from PySide6.QtCore import Qt, Signal, QRect, QPoint, QSize
- from typing import List, Tuple
- import zipfile
- import pandas
- import numpy
- import math
- import sys
- class ArrowPointerIndicator(QWidget):
- minimumValueChange: Signal = Signal(float)
- maximumValueChange: Signal = Signal(float)
- valueChanged: Signal = Signal(float)
- def __init__(self, chunks: List[Tuple[float, QColor]], lineWidth: int = 5, parent: QWidget = None) ->None:
- super().__init__(parent)
- self.__arrowColor: QColor = QColor(255, 0, 0)
- self.__gradient: QConicalGradient = None
- self.setChunks(chunks)
- self.__arrow = QPolygon([
- QPoint(-2, -80),
- QPoint(0, -100),
- QPoint(2, -80),
- QPoint(2, 10),
- QPoint(-2, 10),
- QPoint(-2, -80)
- ])
- self.__minimum = -90.0
- self.__maximum = 90.0
- self.__lineWidth = lineWidth
- self.__value: float = 0.0
- def valueRange(self) ->(float, float):
- return (self.__minimum, self.__maximum)
- def setValueRange(self, minimum: float, maximum: float) ->None:
- if self.__minimum != minimum:
- self.__minimum = minimum
- self.update()
- if self.__maximum != maximum:
- self.__maximum = maximum
- self.update()
- def value(self) ->float:
- return self.__value
- def setValue(self, value: float) ->None:
- if self.__value == value:
- return
- self.__value = max(min(value, self.__maximum), self.__minimum)
- self.valueChanged.emit(self.__value)
- self.update()
- def lineWidth(self) ->int:
- return self.__lineWidth
- def setLineWidth(self, lineWidth: int) ->None:
- if self.__lineWidth == lineWidth:
- return
- self.__lineWidth = lineWidth
- self.update()
- def arrowColor(self) ->QColor:
- return self.__arrowColor
- def setArrowColor(self, arrowColor: QColor) ->QColor:
- if self.__arrowColor == arrowColor:
- return
- self.__arrowColor = arrowColor
- self.update()
- def setChunks(self, chunks: List[Tuple[float, QColor]]) ->None:
- weightsSum: float = sum(item[0] for item in chunks)
- chunks = [(item[0] / weightsSum / 2, item[1]) for item in chunks]
- self.__gradient = QConicalGradient()
- passedWeight = 0.25
- for weight, color in chunks:
- self.__gradient.setColorAt(passedWeight, color)
- self.__gradient.setColorAt(passedWeight + weight - 0.0000000001, color)
- passedWeight += weight
- self.__gradient.setCenter(QPoint(0, 0))
- self.__gradient.setAngle(-90)
- self.update()
- def paintEvent(self, event: QPaintEvent) ->None:
- super().paintEvent(event)
- drawSize = self.width() / 2
- painter = QPainter(self)
- painter.drawRect(QRect(1, 1, self.width() - 2, self.height() - 2))
- painter.translate(drawSize, drawSize)
- painter.setRenderHint(QPainter.RenderHint.Antialiasing)
- self.__drawColorArc(drawSize, painter)
- self.__drawArrowPointer(drawSize, painter)
- def __drawColorArc(self, drawSize: int, painter: QPainter) ->None:
- drawingRect = QRect(-drawSize, -drawSize, 2 * drawSize, 2 * drawSize)
- excludeRect = QRect(-drawSize + self.__lineWidth, -drawSize + self.__lineWidth, 2 * (drawSize - self.__lineWidth), 2 * (drawSize - self.__lineWidth))
- painter.save()
- outerRegion = QRegion(drawingRect, QRegion.RegionType.Ellipse).subtracted(QRegion(excludeRect, QRegion.RegionType.Ellipse))
- painter.setClipRegion(outerRegion)
- painter.setBrush(QBrush(self.__gradient))
- painter.drawChord(drawingRect, 0, 180 * 16)
- painter.restore()
- def __drawArrowPointer(self, drawSize: int, painter: QPainter) ->None:
- painter.save()
- painter.setBrush(self.__arrowColor)
- painter.scale(drawSize / 100.0, drawSize / 100.0)
- painter.rotate(float(numpy.interp(self.__value, self.valueRange(), (-90, 90))))
- painter.drawConvexPolygon(self.__arrow)
- painter.restore()
- class SizeBoundedWindow(QWidget):
- def __init__(self, parent: QWidget = None) ->None:
- super().__init__(parent)
- def resizeEvent(self, event: QResizeEvent) ->None:
- super().resizeEvent(event)
- if self.width() * 0.6 > self.height():
- self.resize(self.height() / 0.6, self.height())
- self.update()
- elif self.width() * 0.6 < self.height():
- self.resize(self.width(), self.width() * 0.6)
- self.update()
- if __name__ == '__main__':
- app = QApplication(sys.argv)
- indicator_1 = ArrowPointerIndicator([
- (1, Qt.GlobalColor.red),
- (3, Qt.GlobalColor.yellow),
- (2, Qt.GlobalColor.green),
- (3, Qt.GlobalColor.yellow),
- (1, Qt.GlobalColor.red)
- ])
- indicator_2 = ArrowPointerIndicator([
- (10, Qt.GlobalColor.white),
- (1, Qt.GlobalColor.red),
- (1, Qt.GlobalColor.white),
- (1, Qt.GlobalColor.red),
- (10, Qt.GlobalColor.white)
- ], 100000000)
- indicator_1.setArrowColor(QColor(Qt.GlobalColor.black))
- indicator_1.setValueRange(-10, 10)
- indicator_2.setValueRange(-25, 25)
- window = SizeBoundedWindow()
- layout = QGridLayout()
- window.setLayout(layout)
- layout.addWidget(indicator_1, 0, 0, 4, 5)
- layout.addWidget(indicator_2, 1, 1, 2, 3)
- window.show()
- sys.exit(app.exec())
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement