功能:生成星标图形项,并在目标点上将底图颜色反色显示,当定位和拖动后输出底图在标记点的像素值。输入和输出使用信号槽机制。
代码:
import math
import sys
from PySide6.QtCore import QObject, Signal, QPointF, Qt
from PySide6.QtGui import QColor, QPen, QBrush, QPixmap
from PySide6.QtWidgets import QGraphicsPolygonItem, QGraphicsItem, QApplication, QGraphicsScene, QGraphicsView, \
QGraphicsPixmapItem
class StarItem(QGraphicsPolygonItem, QObject):
I_position_signal = Signal(QPointF) # 位置信号(输入)
O_colorCenter_signal = Signal(QColor) # 中心点颜色信号(输出)
I_is_visible_signal = Signal(bool) # 是否可见信号(输入)
def __init__(self, size, baseImageItem, num_points = 5, ratio=0.4, parent=None):
"""
用来标记图片的星标
:param size: 尺寸
:param baseImageItem: 底图
:param num_points: 顶点数
:param ratio: 肥瘦比
:param parent: 父类
"""
QGraphicsPolygonItem.__init__(self, parent=parent)
QObject.__init__(self)
self.outer_radius = size / 2 # 外圆半径
self.inner_radius = size * ratio / 2 # 内圆半径
self.num_points = num_points # 顶点数
self.setPolygon(self.calculate_star_points()) # 设置多边形
self.setAcceptHoverEvents(True) # 启用鼠标跟踪
self.setFlag(QGraphicsItem.ItemIsMovable, True) # 设置可移动
self.basePixmapItem = baseImageItem # 获取底图图片项
self.basePixmap = self.basePixmapItem.pixmap() # 获取底图图片
# 如果本星标没有父类,则设置底图为父类
if parent is None:
self.parent = self.basePixmapItem # 设置父类
self.colorCenter = QColor(0, 0, 0) # 中心点的颜色
self.signalAndSlot() # 信号与槽
# self.showPoints()
def signalAndSlot(self):
"""
信号与槽
:return:
"""
self.I_position_signal.connect(self.setPos) # 连接信号与槽setPos
def getInverseColor(self, color):
"""
获取反色
:param color:
:return:
"""
r = 255 - color.red()
g = 255 - color.green()
b = 255 - color.blue()
return QColor(r, g, b)
def setColor(self):
"""
获取中心点颜色,设置画刷和画笔颜色
:return:
"""
# pos = self.mapToItem(self.basePixmapItem, self.mapFromParent(self.pos()))
pos_scene = self.mapToScene(QPointF(0, 0)) # 获取中心点所在位置在场景中的坐标
pos_base = self.basePixmapItem.mapFromScene(pos_scene) # 获取中心点所在位置映射到底图的坐标
self.colorCenter = self.basePixmap.toImage().pixelColor(pos_base.toPoint()) # 获取鼠标所在位置的像素颜色
self.setPen(QPen(QColor(self.colorCenter), 2)) # 设置画笔
# print(self.colorCenter)
color = self.getInverseColor(self.colorCenter) # 设置反色
self.setBrush(QBrush(color)) # 设置画刷
# ###########如果需要不同的外轮廓颜色###############
# self.setPen(QPen(QColor("red")))
# #############################################
self.setPen(QPen(QColor(color), 2)) # 设置画笔
self.O_colorCenter_signal.emit(self.colorCenter) # 发送信号colorCenter
# 重写设置位置函数,使星标的参考点在中心
def setPos(self, pos):
x = pos.x() # 使星标的参考点在中心
y = pos.y()
self.setColor() # 设置中心点颜色
super().setPos(x, y) # 调用父类的设置位置函数
def hoverEnterEvent(self, event):
pass
def hoverLeaveEvent(self, event):
pass
# 重写鼠标移动事件,使星标的颜色与背景图片反色,突出显示
def mouseMoveEvent(self, event):
self.setColor()
super().mouseMoveEvent(event)
def calculate_star_points(self):
"""
计算顶点坐标
:return:
"""
points = []
angle_step = 2 * math.pi / self.num_points
start_angle = -0.5 * math.pi
for i in range(self.num_points * 2):
if i % 2 == 0:
current_radius = self.outer_radius
else:
current_radius = self.inner_radius
angle = i * angle_step / 2 + start_angle
y = current_radius * math.sin(angle)
x = current_radius * math.cos(angle)
points.append(QPointF(x, y))
return points
if __name__ == "__main__":
app = QApplication(sys.argv)
# 创建场景和视图
scene = QGraphicsScene()
view = QGraphicsView(scene)
# 创建底图
pixmap = QPixmap("you/image/path")
pixmap_item = QGraphicsPixmapItem(pixmap)
scene.addItem(pixmap_item)
# 创建星标
star = StarItem(30, pixmap_item, num_points=5, ratio=0.3)
scene.addItem(star)
# 显示
view.show()
# 运行
sys.exit(app.exec())