【问题标题】:Qt insert QGraphicsItem in scene on click positionQt在点击位置的场景中插入QGraphicsItem
【发布时间】:2023-03-16 01:51:01
【问题描述】:

我正在设计一个绘制电路模型的应用程序,我需要通过单击按钮在场景中插入元素,然后在场景中插入元素。

它应该工作的方式如下:我按下按钮插入一个节点,然后它显示一条消息说“按下你要插入元素的位置”,你按下,元素出现在屏幕上。

我认为问题在于我必须停止代码以获取位置然后继续或类似的东西。

下面我展示了部分代码(原文包含更多的类和第二个计算选项卡,这个问题不需要它并且没有以任何方式连接):

from PyQt5 import sip
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import QRectF, Qt, QSize, QPointF, QPoint, QLineF, showbase
from PIL import Image
import calculation


class Main(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Nodal Equations")
        self.setWindowIcon(QIcon("images/flash.ico"))
        self.setGeometry(150,50,1650,950)
        self.setFixedSize(self.size())

        self.UI()
        self.show()

    def UI(self):
        self.toolBar()
        self.tabwidgets()
        self.widgets()
        self.layouts()


    def toolBar(self):
        self.tb = QToolBar("Toolbar")
        self.addToolBar(Qt.RightToolBarArea, self.tb)
        self.tb.setIconSize(QSize(50,50))

        # Toolbar buttons
        self.addNode = QAction(QIcon("images/node.png"),"Node",self)
        self.tb.addAction(self.addNode)
        self.addNode.triggered.connect(self.funcAddNode)
        self.tb.addSeparator()



    def tabwidgets(self):
        self.tabs = QTabWidget()
        self.tabs.blockSignals(True) # To update tabs. After defining every layout we have to set it to False
        self.setCentralWidget(self.tabs) # If this is not used, we cannot see the widgets (Needed if we use QMainWindow)
        self.modelViewTab = QWidget()
        self.tabs.addTab(self.modelViewTab, "Model View")

    def widgets(self):
        # Model View widgets
        self.view = ModelView()
        self.instructionsLabel = QLabel("Welcome to Node Equations Solver. To start select an order on the toolbar menu", self)


    def layouts(self):
        # Model View Tab layouts
        self.mainModelLayout = QVBoxLayout()
        self.sceneLayout = QHBoxLayout()
        self.instructionsLayout = QHBoxLayout()
        self.mainModelLayout.setAlignment(Qt.AlignCenter)

        ##### Adding widgets
        self.sceneLayout.addWidget(self.view)

        self.instructionsLayout.addWidget(self.instructionsLabel)

        ##### Adding layouts
        self.mainModelLayout.addLayout(self.sceneLayout)
        self.mainModelLayout.addLayout(self.instructionsLayout)

        self.modelViewTab.setLayout(self.mainModelLayout)
        

    def funcAddNode(self):
        self.node = Node(0,500,500)
        self.view.scene.addItem(self.node)


class Node(QGraphicsEllipseItem):
    def __init__(self,number, x, y):
        super(Node, self).__init__(0, 0, 10, 10)
        self.number = number

        self.setPos(x, y)
        self.setBrush(Qt.yellow)
        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):
        app.instance().setOverrideCursor(Qt.ClosedHandCursor)

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

    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() 
        if updated_cursor_x < 0:
            self.setPos(QPointF(0, updated_cursor_y))
        elif updated_cursor_y < 0:
            self.setPos(QPointF(updated_cursor_x, 0))
        elif updated_cursor_x + self.boundingRect().right() > 1550:
            self.setPos(QPointF(1550 - self.boundingRect().width(), updated_cursor_y))
        elif updated_cursor_y + self.boundingRect().bottom() > 840:
            self.setPos(QPointF(updated_cursor_x, 840 - self.boundingRect().height()))
        else:
            self.setPos(QPointF(updated_cursor_x, updated_cursor_y))





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

        self.setRenderHints(QPainter.Antialiasing)

        self.scene = QGraphicsScene()
        self.setScene(self.scene)
        self.setSceneRect(0, 0, 1550, 840)

    ##### This is a way I tried to pick the cursor position and store it, but it didn't work
    # def mousePressEvent(self, event):
    #     x = event.scenePos().x()
    #     y = event.scenePos().y()
        
    #     return (x,y)


def main():
    global app
    app = QApplication(sys.argv)
    window = Main()
    sys.exit(app.exec_())

if __name__ == "__main__":
    main()

【问题讨论】:

    标签: python qt model qgraphicsview cursor-position


    【解决方案1】:

    您需要将return (x,y) 更改为有用的东西,即发出信号或实际添加元素。

    mousePressEvent 是一个不返回任何内容的方法(C++ 中的void)。

    【讨论】:

    • 类似的东西。我正在考虑使用装饰器或其他东西。我会设计一个菜单让用户输入一些元素参数,比如节点名称,按下按钮后,代码会询问你输入的位置,然后将元素放在那里。完成后我会进行编辑
    猜你喜欢
    • 2014-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多