如何解决如何根据任意文本长度获取 QGraphicsItem 的 boundingRect
我正在继承 QGraphicsItem
以创建一个绘制图标(基于多边形点的常量字典)和文本标签的地图标记。
下面的 boundingRect
方法定义了一个固定的边界框矩形。但是由于文本标签可以是任意长度,我需要每个标记实例的边界框都不同(例如,用于选择和聚焦)。
如何根据字符在屏幕上占据的实际像素宽度获取每个标记实例的边界矩形?我是否需要根据字体大小和字符数创建手动估算?或者 Qt 可以自动计算吗?
import sys
from PySide6 import QtCore,QtWidgets
from PySide6.QtWidgets import (
QApplication,QWidget,QHBoxLayout,QVBoxLayout,QGraphicsScene,QGraphicsView,QGraphicsItem
)
from PySide6.QtGui import QColor,QFont,QPen,QBrush,Qpolygon
from PySide6.QtCore import QPointF,Qt,QRectF,QPoint
MARKERS = {
'peak': {'color': 'limegreen','shape': 'star'},'tag': {'color': 'bisque','shape': 'x'},'pole': {'color': 'coral','shape': 'circle'}
}
SHAPES = {
'star': [(-1,-1),(0,-5),(1,(5,4),1),(-5,(-1,-1)],'x': [(0,-2),(3,-3),(2,0),3),5),2),(-3,(-2,-5)]
}
class MainWindow(QWidget):
def __init__(self):
super().__init__()
self.setwindowTitle('Map')
self.scene = MapScene()
self.view = QGraphicsView(self.scene)
# Main layout
layout = QHBoxLayout()
layout.addWidget(self.view)
self.setLayout(layout)
class MapMarker(QGraphicsItem):
def __init__(self,marker,label):
super().__init__()
self.marker = marker
self.label = label
# Build Qpolygon dictionary from SHAPES coordinates
self.shapes = {}
for k,v in SHAPES.items():
self.shapes[k] = Qpolygon([QPoint(*point)for point in SHAPES[k]])
# Set marker color
self.color = QColor(MARKERS[self.marker]['color'])
def paint(self,painter,option,widget):
brush = QBrush(Qt.solidPattern)
brush.setColor(self.color)
painter.setPen(QPen(self.color))
painter.setBrush(brush)
# Draw marker shape
shape_name = MARKERS[self.marker]['shape']
if shape_name == 'circle':
painter.drawEllipse(-4,-4,8,8)
else:
painter.drawpolygon(self.shapes[shape_name])
# Draw marker label
painter.drawText(10,-2,self.label)
def boundingRect(self):
return QRectF(-10,-15,200,30)
class MapScene(QGraphicsScene):
def __init__(self):
super().__init__()
markers = [
(10,10,'peak','Some peak'),(20,30,'tag','Some tag with a longer name'),]
# Draw markers
for x,y,m,b in markers:
marker = MapMarker(m,b)
marker.setPos(x,y)
self.addItem(marker)
if __name__ == '__main__':
app = QApplication([])
widget = MainWindow()
widget.show()
sys.exit(app.exec())
解决方法
您可以使用 QFontMetrics 或 QFontMetricsF(从 QtGui 导入)获取文本的 boundingRect
,并与图标的 boundingRect
合并。
def boundingRect(self):
shape_name = MARKERS[self.marker]['shape']
if shape_name == 'circle':
icon_rect = QRectF(-4,-4,8,8)
else:
icon_rect = QRectF(self.shapes[shape_name].boundingRect())
text_rect = QFontMetricsF(QFont()).boundingRect(self.label).translated(10,-2)
return icon_rect | text_rect
我在 paint
的末尾添加了这些行以验证照片中矩形的区域:
painter.setPen(QPen(Qt.black,1,Qt.DashLine))
painter.setBrush(Qt.NoBrush)
painter.drawRect(self.boundingRect())
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。