PyQt5 QGraphicsPathItem 绘制一个电阻

Posted

技术标签:

【中文标题】PyQt5 QGraphicsPathItem 绘制一个电阻【英文标题】:PyQt5 QGraphicsPathItem to draw a Resistor 【发布时间】:2021-12-31 10:03:06 【问题描述】:

我正在编写一个应用程序来解决电路问题,我需要对电路进行建模。为此,我需要在场景中绘制电阻器和其他形状,并能够移动它等等。

问题是我试图在现场展示一个电阻,但我找不到路。我正在尝试使用 QGraphicsPathItem 但查看文档我无法做到这一点。我将展示一些我正在编写的用于解决应用程序这一部分的代码:

1.我显示的第一个代码是应该显示的电阻器

2。第二部分是我想要做的方式,但不是省略号,我想显示一个电阻

### 1st Code

import sys
from PyQt5 import QtCore, QtGui, QtWidgets, uic
from PyQt5.QtCore import Qt

x0 = 100
y0 = 50

class MainWindow(QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()

        self.x1 = 12
        self.y1 = 33
        self.y2 = 18
        self.y3 = 15
        self.y4 = 9
        self.y5 = 3

        self.p1 = QtCore.QPoint(0, 0 + self.y1)
        self.p2 = QtCore.QPoint(0, 0 + self.y2)
        self.p3 = QtCore.QPoint(self.x1, self.y3)
        self.p4 = QtCore.QPoint(-self.x1, self.y4)
        self.p5 = QtCore.QPoint(self.x1, self.y5)
        self.p6 = QtCore.QPoint(-self.x1, -self.y5)
        self.p7 = QtCore.QPoint(self.x1, -self.y4)
        self.p8 = QtCore.QPoint(-self.x1, -self.y3)
        self.p9 = QtCore.QPoint(0, 0 - self.y2)
        self.p10 = QtCore.QPoint(0, 0 - self.y1)

        

    def draw_resistor(self,angle=0, x0=0, y0=0):
        self.x0 = x0
        self.y0 = y0
        self.label = QtWidgets.QLabel()
        self.canvas = QtGui.QPixmap(200, 100) # This is to create the canvas
        self.canvas.fill() # To set the canvas background color to white. If not, we will only see a black frame
        self.label.setPixmap(self.canvas)
        self.setCentralWidget(self.label)
        self.painter = QtGui.QPainter(self.label.pixmap())
        self.painter.translate(self.x0,self.y0) # To change the axis origin
        self.painter.rotate(angle)
        self.painter.drawLines(self.p1,self.p2,self.p2,self.p3,self.p3,self.p4,self.p4,self.p5,self.p5,
                               self.p6,self.p6,self.p7,self.p7,self.p8,self.p8,self.p9,self.p9,self.p10)
        self.painter.end()

    def rotate(self,angle=0):
        self.painter.rotate(angle)
        self.painter.drawLines(self.p1,self.p2,self.p2,self.p3,self.p3,self.p4,self.p4,self.p5,self.p5,
                               self.p6,self.p6,self.p7,self.p7,self.p8,self.p8,self.p9,self.p9,self.p10)
        self.label.update() # Research about this, it could be the key




app = QtWidgets.QApplication(sys.argv)
window = MainWindow()
window.show()
window.draw_resistor(45,x0,y0)
app.exec_()

###################
###################
###################
###################


### 2nd Code

import sys
from PyQt5.QtWidgets import QApplication, QGraphicsItem, QGraphicsPathItem, QGraphicsView, QGraphicsScene, QGraphicsEllipseItem, QLabel
from PyQt5.QtCore import Qt, QPointF, QRectF, QPoint
from PyQt5.QtGui import QPixmap, QPainter

class MovingObject(QGraphicsEllipseItem):
    def __init__(self, x, y, r):
        super().__init__(0, 0, r, r)
        self.setPos(x, y)
        self.setBrush(Qt.blue)
        self.setAcceptHoverEvents(True)

    # Mouse hover events
    def hoverEnterEvent(self, event):
        app.instance().setOverrideCursor(Qt.OpenHandCursor)

    def hoverLeaveEvent(self, event):
        app.instance().restoreOverrideCursor()

    # Mouse click events
    def mousePressEvent(self, event):
        pass

    def mouseMoveEvent(self, event):
        orig_cursor_position = event.lastScenePos()
        updated_cursor_position = event.scenePos()

        orig_position = self.scenePos()

        updated_cursor_x = updated_cursor_position.x() - orig_cursor_position.x() + orig_position.x()
        updated_cursor_y = updated_cursor_position.y() - orig_cursor_position.y() + orig_position.y()
        self.setPos(QPointF(updated_cursor_x, updated_cursor_y))

    def mouseReleaseEvent(self, event):
        print("x: 0, y: 1".format(self.pos().x(), self.pos().y()))


class GraphicView(QGraphicsView):
    def __init__(self):
        super().__init__()

        self.scene = QGraphicsScene()
        self.setScene(self.scene)
        self.setSceneRect(0, 0, 1200, 1000)

        self.moveObject = MovingObject(50, 50, 40)
        self.moveObject2 = MovingObject(100, 100, 100)
        self.scene.addItem(self.moveObject)
        self.scene.addItem(self.moveObject2)


app = QApplication(sys.argv)

view = GraphicView()
view.show()

sys.exit(app.exec_())

【问题讨论】:

您说您正在尝试使用 QGraphicsPathItem,但您的代码中没有任何内容。如果要使用 QGraphicsPathItem,为什么要使用 QGraphicsEllipseItem?您是否研究过您正在使用的类的文档,它们是QGraphicsPathItem、它的继承类(QAbstractGraphicsShapeItem 和QGraphicsItem)和QPainterPath? 对不起,我忘了添加。我刚刚解决了这个问题,我把它留在下一个答案中 【参考方案1】:

我解决了,这就是解决方案:

class Resistor(QGraphicsPathItem):
    def __init__(self, x, y):
        super(Resistor, self).__init__()
        self.setFlag(QGraphicsItem.ItemIsSelectable, True)
        self.setFlag(QGraphicsItem.ItemIsFocusable, True)
        self.setAcceptHoverEvents(True)
        self.isSelected = False
        self.setPath(self.create_path())
        self.setPos(x, y)
    
    def create_path(self):
        path = QPainterPath()

        path.moveTo(0, 33)
        path.lineTo(0, 18)
        path.lineTo(12, 15)
        path.lineTo(-12, 9)
        path.lineTo(12, 3)
        path.lineTo(-12, -3)
        path.lineTo(12, -9)
        path.lineTo(-12, -15)
        path.lineTo(0, -18)
        path.lineTo(0, -33)

        return path

【讨论】:

以上是关于PyQt5 QGraphicsPathItem 绘制一个电阻的主要内容,如果未能解决你的问题,请参考以下文章

如何删除列出的“QGraphicsPathItem”对象以控制进程内存使用?

为啥不更新重绘场景?

在 QQuickWidget 中更新/重绘仪表

如何使用 blit 有效地重绘多个 matplotlib 图

PyQt5 GUI 仅在单击屏幕并重新打开时更新

如何在 Pyqt5 环境中使用 Pickle 保存 Matplotlib 图?