- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一条构成符号的路径,我想知道 QPainter 是否可以绘制该路径。在阅读文档时,我看到有一个与 QPainter
关联的 drawPath
函数,但每次我尝试实现它时,我总是收到一个错误,提示 QPainter::drawPath:画家未激活
。
因为我没有任何成功的尝试,所以我添加了代码的最小化工作版本。它将为您提供一些基本的缩放和平移功能以及选择符号以及按住 Shift 键取消选择符号的功能。
我希望路径在被选择或悬停时改变颜色,并且当前在被选择或悬停时被填充。最终,我希望用户能够从一开始就将路径更改为虚线或颜色。
感谢您的建议和帮助。
代码
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtSvg import *
import sys
from math import sqrt,cos,acos,asin,degrees,pi
class LogObject(QObject):
hovered = pyqtSignal()
notHovered = pyqtSignal()
def figAngle(radius,opposite):
dist = sqrt((radius) ** 2 + (opposite) ** 2)
angle = degrees(asin(opposite/dist))
if angle < 0:
angle = angle + 360
return angle
def create_path():
scale = 250
path = QPainterPath()
path.addEllipse(QPointF(0,0), 0.0268, 0.0268) # Using QPointF will center it
startAngle = figAngle(0.0357/scale,0.0045/scale) # Use the scale so that it will adjust as it is scaled
endAngle = figAngle(0.0357/scale,-0.0092/scale)
path.moveTo((0.0357+0.0821),0.0045 )
path.arcTo(QRectF(-0.0357,-0.0357,(0.0357*2),(0.0357*2)),-startAngle,-endAngle)
path.moveTo(0.0357, -0.0045)
path.lineTo(0.0357 + 0.0821, -0.0045)
path.lineTo(0.0357+0.0821,-0.0045-0.0680)
path.lineTo(0.0357+0.0821+0.1450,-0.0045-0.0680)
path.lineTo(0.0357+0.0821+0.1450,-0.0045-0.0680+0.1450)
path.lineTo(0.0357+0.0821,-0.0045-0.0680+0.1450)
path.lineTo(0.0357+0.0821,-0.0045-0.0680+0.1450-0.0680)
path.moveTo(0.0357+0.0821+0.0090,-0.0045-0.0680+0.1450-0.0090)
path.addRect(0.0357+0.0821+0.0090, -0.0045-0.0680+0.1450-0.0090-0.1270, 0.1270, 0.1270)
tr = QTransform()
tr.scale(scale, scale)
path = tr.map(path)
return path
class Point(QGraphicsPathItem):
def __init__(self, x, y, r, name):
super(Point, self).__init__()
self.setFlag(QGraphicsItem.ItemIsSelectable, True)
self.setPath(create_path())
self.setScale(1)
self.setRotation(180+r)
self.setAcceptHoverEvents(True)
self.log = LogObject()
self.setPos(x, y)
self.isSelected = False
def itemChange(self, change, value):
if change == self.ItemSelectedChange:
self.setBrush(QBrush(Qt.green) if value else QBrush(Qt.black))
return QGraphicsItem.itemChange(self, change, value)
def hoverEnterEvent(self, event):
self.setBrush(QColor("red"))
self.log.hovered.emit()
QGraphicsItem.hoverMoveEvent(self, event)
def hoverLeaveEvent(self, event):
if self.isSelected == True:
self.setBrush(QBrush(Qt.green))
else:
self.setBrush(QColor("black"))
self.log.notHovered.emit()
QGraphicsItem.hoverMoveEvent(self, event)
class Viewer(QGraphicsView):
photoClicked = pyqtSignal(QPoint)
rectChanged = pyqtSignal(QRect)
def __init__(self, parent):
super(Viewer, self).__init__(parent)
self.setRenderHints(QPainter.Antialiasing)
self._zoom = 0
self._empty = True
self.setScene(QGraphicsScene(self))
self.setTransformationAnchor(QGraphicsView.AnchorUnderMouse)
self.setResizeAnchor(QGraphicsView.AnchorUnderMouse)
self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.setFrameShape(QFrame.NoFrame)
self.area = float()
self.setPoints()
self.viewport().setCursor(Qt.ArrowCursor)
QTimer.singleShot(0, self.reset_fit)
self.selectedItems = []
def setItems(self):
self.data = {
"x": [
-2414943.8686,
-2417160.6592,
-2417160.6592,
-2416009.9966,
-2416012.5232,
-2416012.5232,
],
"y": [
10454269.7008,
10454147.2672,
10454147.2672,
10453240.2808,
10455255.8752,
10455255.8752,
],
"rotation":[
313.9962,
43.9962,
223.9962,
313.9962,
43.9962,
223.9962,
]
}
for i, (x, y,r) in enumerate(zip(self.data["x"], self.data["y"],self.data["rotation"])):
p = Point(x, y,r, "Point__" + str(i))
p.log.hovered.connect(self.hoverChange)
p.log.notHovered.connect(self.notHoverChange)
self.scene().addItem(p)
def setPoints(self):
self.setItems()
self.setDragMode(self.ScrollHandDrag)
def wheelEvent(self, event):
if event.angleDelta().y() > 0:
factor = 1.25
self._zoom += 1
else:
factor = 0.8
self._zoom -= 1
if self._zoom > 0:
self.scale(factor, factor)
elif self._zoom == 0:
self.reset_fit()
else:
self._zoom = 0
def hoverChange(self):
self.viewport().setCursor(Qt.PointingHandCursor)
def notHoverChange(self):
self.viewport().setCursor(Qt.ArrowCursor)
def mousePressEvent(self, event):
if event.button() == Qt.LeftButton:
singleItem = self.itemAt(event.pos().x(), event.pos().y())
if singleItem != None:
if QApplication.keyboardModifiers() == Qt.ShiftModifier: # This will determine if the shift key is depressed
if singleItem.isSelected == True:
singleItem.setSelected(False)
singleItem.isSelected = False
self.selectedItems.remove(singleItem)
elif singleItem.isSelected == False:
singleItem.setSelected(True)
singleItem.isSelected = True
self.selectedItems.append(singleItem)
return
elif event.button() == Qt.MidButton:
self.viewport().setCursor(Qt.ClosedHandCursor)
self.original_event = event
handmade_event = QMouseEvent(
QEvent.MouseButtonPress,
QPointF(event.pos()),
Qt.LeftButton,
event.buttons(),
Qt.KeyboardModifiers(),
)
QGraphicsView.mousePressEvent(self, handmade_event)
super(Viewer, self).mousePressEvent(event)
def mouseReleaseEvent(self, event):
if event.button() == Qt.MidButton:
self.viewport().setCursor(Qt.ArrowCursor)
handmade_event = QMouseEvent(
QEvent.MouseButtonRelease,
QPointF(event.pos()),
Qt.LeftButton,
event.buttons(),
Qt.KeyboardModifiers(),
)
QGraphicsView.mouseReleaseEvent(self, handmade_event)
def reset_fit(self):
r = self.scene().itemsBoundingRect()
self.resetTransform()
self.setSceneRect(r)
self.fitInView(r, Qt.KeepAspectRatio)
self._zoom = 0
self.scale(1, -1)
class Window(QWidget):
def __init__(self):
super(Window, self).__init__()
self.viewer = Viewer(self)
VBlayout = QVBoxLayout(self)
VBlayout.addWidget(self.viewer)
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
window = Window()
window.setGeometry(500, 300, 800, 600)
window.show()
sys.exit(app.exec_())
最佳答案
您不必在 QGraphicsPathItem 中使用 QPainter,您必须使用 setPen() 设置 QPen。
<小时/>QGraphicsPathItem已经有一个只能在paint()方法中使用的QPainter,但在这种情况下没有必要,现有的QGraphicsItems如QGraphicsRectItem,QGraphicsEllipseItem等没有必要使用它们,因为这些方法继承自QAbstractGraphicsShapeItem并分别使用 setPen() 和 setBrush() 方法支持 QPen 和 QBrush。
我在代码中看到的另一个问题是,您正在使用 isSelected 属性,但您不应该这样做,已经有一个具有该名称的方法,因此您必须使用 isSelected()。
考虑到之前的解决方案是:
class Point(QGraphicsPathItem):
def __init__(self, x, y, r, name):
super(Point, self).__init__()
self.setFlag(QGraphicsItem.ItemIsSelectable, True)
self.setPath(create_path())
self.setScale(10)
self.setRotation(180 + r)
self.setAcceptHoverEvents(True)
self.log = LogObject()
self.setPos(x, y)
pen = QPen(Qt.red)
pen.setStyle(Qt.DashLine)
self.setPen(pen)
def itemChange(self, change, value):
if change == self.ItemSelectedChange:
color = QColor(Qt.green) if value else QColor("black")
# self.setBrush(color)
pen = self.pen()
pen.setColor(color)
self.setPen(pen)
return QGraphicsItem.itemChange(self, change, value)
def hoverEnterEvent(self, event):
color = QColor("red")
# self.setBrush(color)
pen = self.pen()
pen.setColor(color)
self.setPen(pen)
self.log.hovered.emit()
QGraphicsItem.hoverMoveEvent(self, event)
def hoverLeaveEvent(self, event):
color = QColor(Qt.green) if self.isSelected() else QColor("black")
# self.setBrush(color)
pen = self.pen()
pen.setColor(color)
self.setPen(pen)
self.log.notHovered.emit()
QGraphicsItem.hoverMoveEvent(self, event)
关于python - PyQt5 QGraphicsPathItem 由 QPainter 绘制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55754220/
我在使用 QPainter 绘制不同颜色的线条和文本时遇到问题。我正在使用以下代码来实现此目的,但它不起作用。线条和文本都是使用绘制文本的颜色集绘制的。 void MyWidget::drawHorL
我正在尝试使用 QPainter(QT5.8,win64)绘制一个带有多个孔的多边形。我正在使用以下代码: QPainter pm(&image); QPen p(Qt::gray, 2); p.se
我要做什么 –对Qt编写的共享库进行JNI调用。在C++方面,我正在使用QPainter和QSvgRender来处理svg图像并返回一个简单的QImage。 QImage im; QPainter p
我有一些需要大量绘画的饼形小部件。所以我想在 QPainter 在 PaintEvent 中绘制后对其进行缓存。并稍后重用它。有没有直接或黑客的方法来做到这一点? 最佳答案 使用QPixmap作为缓存
是否有机会找出QPainter的大小?我正在使用 QPainter 来绘制移动应用程序的整个图形界面。问题是某些应用程序在窗口上覆盖了每个设备大小不同的菜单,从而使事情几乎不可能!是否有可能在不知道
上下文 我有一个自定义小部件,它应该制作点移动的动画,以便制作一种加载小部件。为了实现这个目标,我开始使用 QPainter 和 QVariantAnimation 对象,这似乎是完成这项工作的不错的
我有一个自定义的 QQuickPaintedItem,它可以绘制用户用鼠标在其上绘制的任何内容。到目前为止,实现非常简单,只需绘制整个图像,即使在放大时也是如此。我注意到放大和平移图像时 FPS 真的
我正在尝试在具有白色背景的 QFrame 上绘制两个具有相同颜色和透明度的矩形。这些矩形应该重叠并且它们的透明度不应该改变(也在重叠区域)。所以像这样: 这是我目前的代码: class Canvas
我有下面的代码通过QPainter显示一些文本 QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing); paint
我使用下面的代码在qt中绘制一个图的轴: ... static const std::array horizontalAxis = { QPointF(0.f,0.f), QPointF(1.
我想在整个圆圈周围绘制那些黑点,彼此之间有规则的间距(下图的粗略图)。那些黑点应该直接坐在圆圈上。有没有一种简单的方法可以用 painter.drawArc() 函数或类似的东西来做这件事? 最佳答案
我正在学习 Qt。我没有意识到 the exercise of chapter 11 of Qt tutorial ,上面写着“当炮弹在空中时改变大炮的颜色”。我选择在 paintCannon 函数中
我创建了一个名为 painter 的类,并在将 QMainWindow 作为参数传递的构造函数中创建了 QPainter p。 所以在 mainwindow.h 中我添加了: protected:
我是Qt初学者,想用QPainter。 我的流程是这样的:我从串口接收数据坐标(x,y),比如(1,1), (2,3),等。我想在每次收到数据时在窗口中绘制这些点。 我看到 QPainter 在事件中
我有一个 QWidget,我在其中使用 QPainter 对象绘制一些点,但是当调用 update() 方法时,QWidget 的绘制被完全清除。有什么方法可以保存实际状态并只添加点,或者我必须保存每
这是我第一次使用 Qt,我必须制作一个与 Qt 等效的 MSPaint。然而,我在画线时遇到了麻烦。我目前可以通过单击屏幕上的某处并在其他地方释放来绘制一条线,但是当我绘制第二条线时,前一条线将被删除
以下代码会导致一堆错误: void MainWindow::displayBoard() { QPixmap pix(0,0); pix.fill(Qt::white); QP
我对书中示例和我的版本之间的差异感到困惑。Qt 版本 5.12.0 如示例所示: 从我的输出中可以看出: 首先,目标和源 In/Atop 模式的图片不同。而且,另一件值得注意的事情是,我们可以将矩形视
问题很简单!我想要这样的东西。要么使用 QPainter类或使用 Qt 图形框架 : 最佳答案 有几种方法可以使用 QPainterPath 来做到这一点。指定 here . 这是该页面的第二个示例:
默认情况下,QPainter 的原点位于左上角。我想绘制形状,但我拥有的所有坐标都在笛卡尔系统中。所以我的问题 - 如何将原点更改为左下角?当然,我可以 scale(1,-1) 但 drawText(
我是一名优秀的程序员,十分优秀!