def __init__(self, *args, **kwargs):
kwargs.setdefault('width', 2)
avatar = kwargs.setdefault('avatar', 'tuga')
self.size = kwargs.pop('size', 45)
self.validate_avatar(avatar)
self.graphics_item = cursor = QtSvg.QGraphicsSvgItem()
# Loads from turtleart.svg
cursor.setSharedRenderer(svg_renderer)
cursor.setElementId(avatar)
# Define local transforms
rect = cursor.sceneBoundingRect()
curr_width, curr_height = rect.width(), rect.height()
cursor.setTransform(QtGui.QTransform(
1.00, 0.00,
0.00, 1.00,
-curr_width / 2, -curr_height / 2)
)
cursor.setTransformOriginPoint(0.5 * curr_width, 0.5 * curr_height)
cursor.setScale(self.size / curr_width)
cursor.setZValue(1.0)
self.pen = QtGui.QPen(QtGui.QColor(0, 0, 0))
self.brush = QtGui.QBrush(QtGui.QColor(0, 0, 0))
super().__init__(*args, **kwargs)
python类QTransform()的实例源码
def __init__(self, scene=None):
if scene is None:
scene = TurtleScene()
self._scene = scene
super().__init__(scene)
transform = QtGui.QTransform(
1, 0,
0, -1, # Revert y, so it uses the standard axis convention in maths
0, 0
)
self.setTransform(transform)
self._zoomfactor = 1.2
# This will crash if I put it in the module namespace, probably
# because the QApplication instance does not exist yet
_LABEL_HEIGHT = QtGui.QFontMetrics(
_LABEL_FONT).height() + 2 * _LABEL_PADDING
w = self._posLabel = QtWidgets.QLabel(self)
# http://stackoverflow.com/questions/7928519/how-to-make-the-qlabel-background-semi-transparent
# Fourth parameter in color tuple is alpha: 0-transparent; 255-opaque
w.setStyleSheet('color: rgba(0, 0, 0, 196); '
'background-color: rgba(0, 0, 0, 0);'
'padding: %d' % _LABEL_PADDING)
w.setAlignment(QtCore.Qt.AlignRight)
w.setFont(_LABEL_FONT)
w.setGeometry(0, 0, 100, _LABEL_HEIGHT)
self._updatePosLabelText((0, 0))
self._updatePosLabelPosition()
def mouseMoveEvent(self, event):
global now, w
if w.input_rect:
if now is None:
now = event.scenePos()
else:
self.removeItem(self.itemAt(now, QTransform()))
p = event.scenePos()
self.addRect(now.x(), now.y(), abs(now.x() - p.x()), abs(now.y() - p.y()))
def clipping(win):
buf = win.scene.itemAt(now, QTransform()).rect()
win.clip = [buf.left(), buf.right(), buf.top(), buf.bottom()]
for b in win.lines:
pass
win.pen.setColor(blue)
cohen_sutherland(b, win.clip, win)
win.pen.setColor(red)
def draw(self, painter: QPainter) -> None:
if self.sourceIsPixmap():
pixmap, offset = self.sourcePixmap(Qt.LogicalCoordinates, QGraphicsEffect.PadToEffectiveBoundingRect)
else:
pixmap, offset = self.sourcePixmap(Qt.DeviceCoordinates, QGraphicsEffect.PadToEffectiveBoundingRect)
painter.setWorldTransform(QTransform())
painter.setBrush(Qt.black)
painter.drawRect(pixmap.rect())
painter.setOpacity(self.opacity)
painter.drawPixmap(offset, pixmap)
def mouseDoubleClickEvent(self, event):
item = self.itemAt(event.scenePos(), QTransform())
if item != None and item.type() == BBOX:
self.removeItem(item)
self.invalidate()
self.saveLabels()
def __init__(self):
self.refCount = 0
self.image = None
self.pixmap = None
self.transform = QTransform()
self.unscaledBoundingRect = QRectF()
def _validateImage(self):
if (self._sharedImage.transform != DemoItem._transform and not Colors.noRescale) or (self._sharedImage.image is None and self._sharedImage.pixmap is None):
# (Re)create image according to new transform.
self._sharedImage.image = None
self._sharedImage.pixmap = None
self._sharedImage.transform = DemoItem._transform
# Let subclass create and draw a new image according to the new
# transform.
if Colors.noRescale:
transform = QTransform()
else:
transform = DemoItem._transform
image = self.createImage(transform)
if image is not None:
if Colors.showBoundingRect:
# Draw red transparent rect.
painter = QPainter(image)
painter.fillRect(image.rect(), QColor(255, 0, 0, 50))
painter.end()
self._sharedImage.unscaledBoundingRect = self._sharedImage.transform.inverted()[0].mapRect(QRectF(image.rect()))
if Colors.usePixmaps:
if image.isNull():
self._sharedImage.pixmap = QPixmap(1, 1)
else:
self._sharedImage.pixmap = QPixmap(image.size())
self._sharedImage.pixmap.fill(QColor(0, 0, 0, 0))
painter = QPainter(self._sharedImage.pixmap)
painter.drawImage(0, 0, image)
else:
self._sharedImage.image = image
return True
else:
return False
return True
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 __init__(self):
self.refCount = 0
self.image = None
self.pixmap = None
self.transform = QTransform()
self.unscaledBoundingRect = QRectF()
def _validateImage(self):
if (self._sharedImage.transform != DemoItem._transform and not Colors.noRescale) or (self._sharedImage.image is None and self._sharedImage.pixmap is None):
# (Re)create image according to new transform.
self._sharedImage.image = None
self._sharedImage.pixmap = None
self._sharedImage.transform = DemoItem._transform
# Let subclass create and draw a new image according to the new
# transform.
if Colors.noRescale:
transform = QTransform()
else:
transform = DemoItem._transform
image = self.createImage(transform)
if image is not None:
if Colors.showBoundingRect:
# Draw red transparent rect.
painter = QPainter(image)
painter.fillRect(image.rect(), QColor(255, 0, 0, 50))
painter.end()
self._sharedImage.unscaledBoundingRect = self._sharedImage.transform.inverted()[0].mapRect(QRectF(image.rect()))
if Colors.usePixmaps:
if image.isNull():
self._sharedImage.pixmap = QPixmap(1, 1)
else:
self._sharedImage.pixmap = QPixmap(image.size())
self._sharedImage.pixmap.fill(QColor(0, 0, 0, 0))
painter = QPainter(self._sharedImage.pixmap)
painter.drawImage(0, 0, image)
else:
self._sharedImage.image = image
return True
else:
return False
return True
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 get_selected_edge(self, pos: QPointF, transform: QTransform):
return super()._get_selected_edge(pos, transform, horizontal_selection=True)
def get_selected_edge(self, pos: QPointF, transform: QTransform):
return super()._get_selected_edge(pos, transform, horizontal_selection=False)
def _get_selected_edge(self, pos: QPointF, transform: QTransform, horizontal_selection: bool):
x1, x2 = self.x, self.x + self.width
y1, y2 = self.y, self.y + self.height
x, y = pos.x(), pos.y()
spacing = 5
spacing /= transform.m11() if horizontal_selection else transform.m22()
if horizontal_selection:
x1a, x1b = x1 - spacing, x1 + spacing
y1a, y1b = y1, y2
x2a, x2b = x2 - spacing, x2 + spacing
y2a, y2b = y1, y2
else:
x1a, x1b, x2a, x2b = x1, x2, x1, x2
y1a, y1b = min(y1 - spacing, y1 + spacing), max(y1 - spacing, y1 + spacing)
y2a, y2b = min(y2 - spacing, y2 + spacing), max(y2 - spacing, y2 + spacing)
if x1a < x < x1b and y1a < y < y1b:
self.selected_edge = 0
return 0
if x2a < x < x2b and y2a < y < y2b:
self.selected_edge = 1
return 1
self.selected_edge = None
return None
def on_slider_y_scale_value_changed(self, new_value: int):
# Scale Up = Top Half, Scale Down = Lower Half
transform = self.graphics_view.transform()
self.graphics_view.setTransform(QTransform(transform.m11(), transform.m12(), transform.m13(),
transform.m21(), new_value, transform.m23(),
transform.m31(), transform.m32(), transform.m33()))
def _add_line(self, scene, line_index, left, text_str, font, color, offset=0, align_right=False):
y = self._line_height * line_index + offset + self.h * 0.1
if line_index == 1:
self._first_lyrics_line_y = y
metrics = QFontMetricsF(font)
text_width = metrics.width(text_str)
max_text_width = (self.w - left - left)
overflow = text_width - max_text_width
if overflow <= 0:
text = scene.addText(text_str, font)
if align_right:
text.setPos(self.w - left - text_width, y)
else:
text.setPos(left, y)
text.setDefaultTextColor(color)
else:
scale_factor = max_text_width / text_width
if scale_factor >= 0.9:
text = scene.addText(text_str, font)
text.setPos(left, y)
text.setDefaultTextColor(color)
text.setTransform(QTransform().scale(scale_factor, 1.0))
else:
self._extra_lines_after.append(line_index)
idx = len(text_str) // 2
while idx < len(text_str) and not text_str[idx].isspace():
idx += 1
line_index = self._add_line(scene, line_index, left, text_str[:idx], font, color, offset)
line_index += 1
line_index = self._add_line(scene, line_index, left, "\t" + text_str[idx:], font, color,
offset - self._line_height * 0.1)
return line_index
def __init__(self):
self.refCount = 0
self.image = None
self.pixmap = None
self.transform = QTransform()
self.unscaledBoundingRect = QRectF()
def _validateImage(self):
if (self._sharedImage.transform != DemoItem._transform and not Colors.noRescale) or (self._sharedImage.image is None and self._sharedImage.pixmap is None):
# (Re)create image according to new transform.
self._sharedImage.image = None
self._sharedImage.pixmap = None
self._sharedImage.transform = DemoItem._transform
# Let subclass create and draw a new image according to the new
# transform.
if Colors.noRescale:
transform = QTransform()
else:
transform = DemoItem._transform
image = self.createImage(transform)
if image is not None:
if Colors.showBoundingRect:
# Draw red transparent rect.
painter = QPainter(image)
painter.fillRect(image.rect(), QColor(255, 0, 0, 50))
painter.end()
self._sharedImage.unscaledBoundingRect = self._sharedImage.transform.inverted()[0].mapRect(QRectF(image.rect()))
if Colors.usePixmaps:
if image.isNull():
self._sharedImage.pixmap = QPixmap(1, 1)
else:
self._sharedImage.pixmap = QPixmap(image.size())
self._sharedImage.pixmap.fill(QColor(0, 0, 0, 0))
painter = QPainter(self._sharedImage.pixmap)
painter.drawImage(0, 0, image)
else:
self._sharedImage.image = image
return True
else:
return False
return True
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 frameNodes(self, nodes):
if len(nodes) == 0:
return
def computeWindowFrame():
windowRect = self.rect()
windowRect.setLeft(windowRect.left() + 10)
windowRect.setRight(windowRect.right() - 10)
windowRect.setTop(windowRect.top() + 10)
windowRect.setBottom(windowRect.bottom() - 10)
return windowRect
nodesRect = None
for node in nodes:
nodeRectF = node.transform().mapRect(node.rect())
nodeRect = QtCore.QRect(nodeRectF.x(), nodeRectF.y(), nodeRectF.width(), nodeRectF.height())
if nodesRect is None:
nodesRect = nodeRect
else:
nodesRect = nodesRect.united(nodeRect)
windowRect = computeWindowFrame()
scaleX = float(windowRect.width()) / float(nodesRect.width())
scaleY = float(windowRect.height()) / float(nodesRect.height())
if scaleY > scaleX:
scale = scaleX
else:
scale = scaleY
if scale < 1.0:
self.setTransform(QtGui.QTransform.fromScale(scale, scale))
else:
self.setTransform(QtGui.QTransform())
sceneRect = self.sceneRect()
pan = sceneRect.center() - nodesRect.center()
sceneRect.translate(-pan.x(), -pan.y())
self.setSceneRect(sceneRect)
# Update the main panel when reframing.
self.update()
def add_bars(win):
global now
if now is None:
QMessageBox.warning(win, "????????!", "?? ?????? ??????????!")
return
buf = win.scene.itemAt(now, QTransform())
if buf is None:
QMessageBox.warning(win, "????????!", "?? ?????? ??????????!")
else:
buf = buf.rect()
win.clip = [buf.left(), buf.right(), buf.top(), buf.bottom()]
t = abs(win.clip[2] - win.clip[3]) * 0.8
k = abs(win.clip[0] - win.clip[1]) * 0.8
# ?????? ????????? ???????
win.pen.setColor(red)
w.lines.append([[win.clip[0], win.clip[2] + t], [win.clip[0], win.clip[3] - t]])
add_row(w)
i = w.table.rowCount() - 1
item_b = QTableWidgetItem("[{0}, {1}]".format(win.clip[0], win.clip[2] + t))
item_e = QTableWidgetItem("[{0}, {1}]".format(win.clip[0], win.clip[3] - t))
w.table.setItem(i, 0, item_b)
w.table.setItem(i, 1, item_e)
win.scene.addLine(win.clip[0], win.clip[2] + t, win.clip[0], win.clip[3] - t, win.pen)
w.lines.append([[win.clip[1], win.clip[2] + t], [win.clip[1], win.clip[3] - t]])
add_row(w)
i = w.table.rowCount() - 1
item_b = QTableWidgetItem("[{0}, {1}]".format(win.clip[1], win.clip[2] + t))
item_e = QTableWidgetItem("[{0}, {1}]".format(win.clip[1], win.clip[3] - t))
w.table.setItem(i, 0, item_b)
w.table.setItem(i, 1, item_e)
win.scene.addLine(win.clip[1], win.clip[3] - t, win.clip[1], win.clip[2] + t, win.pen)
w.lines.append([[win.clip[0] + k, win.clip[2]], [win.clip[1] - k, win.clip[2]]])
add_row(w)
i = w.table.rowCount() - 1
item_b = QTableWidgetItem("[{0}, {1}]".format(win.clip[0] + k, win.clip[2]))
item_e = QTableWidgetItem("[{0}, {1}]".format(win.clip[1] - k, win.clip[2]))
w.table.setItem(i, 0, item_b)
w.table.setItem(i, 1, item_e)
win.scene.addLine(win.clip[0] + k, win.clip[2], win.clip[1] - k, win.clip[2], win.pen)
w.lines.append([[win.clip[0] + k, win.clip[3]], [win.clip[1] - k, win.clip[3]]])
add_row(w)
i = w.table.rowCount() - 1
item_b = QTableWidgetItem("[{0}, {1}]".format(win.clip[0] + k, win.clip[3]))
item_e = QTableWidgetItem("[{0}, {1}]".format(win.clip[1] - k, win.clip[3]))
w.table.setItem(i, 0, item_b)
w.table.setItem(i, 1, item_e)
win.scene.addLine(win.clip[0] + k, win.clip[3], win.clip[1] - k, win.clip[3], win.pen)