PyQt:QGraphicsView中的鼠标事件

4
我想用PyQt编写一个简单的程序。我有一个QGraphicsScene,希望通过两个RadioButton实现以下2个选项: 1. 生成点:这种方式可以在场景中单击时生成椭圆。 2. 选择点:这种方式可以选择单击的点。
由于我对PyQt和GUI编程都不太熟悉,所以我的主要问题是我不太理解Qt中鼠标事件的工作原理。如果有人能耐心地向我讲解鼠标事件的基础知识,并为上述问题提供一些提示,我将非常感激。我还附上一张图片以可视化该问题。我尝试使用Qt Designer放置小部件,然后创建了一个名为SimpleWindow的子类。
import sys
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtGui import QPen, QBrush
from PyQt5.QtWidgets import QGraphicsScene
import points

class SimpleWindow(QtWidgets.QMainWindow, points.Ui_Dialog):

    def __init__(self, parent=None):
        super(SimpleWindow, self).__init__(parent)
        self.setupUi(self)

        self.graphicsView.scene = QGraphicsScene()
        self.graphicsView.setScene(self.graphicsView.scene)
        self.graphicsView.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignTop)

        self.graphicsView.mousePressEvent = self.pixelSelect


    def pixelSelect(self, event):
        pen = QPen(QtCore.Qt.black)
        brush = QBrush(QtCore.Qt.black)

        x = event.x()
        y = event.y()

        if self.radioButton.isChecked():
            print(x, y)
            self.graphicsView.scene.addEllipse(x, y, 4, 4, pen, brush)

       if self.radioButton_2.isChecked():
            print(x, y)


app = QtWidgets.QApplication(sys.argv)
form = SimpleWindow()
form.show()
app.exec_()

这是由设计师生成的类:
from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_Dialog(object):
    def setupUi(self, Dialog):
        Dialog.setObjectName("Dialog")
        Dialog.resize(538, 269)
        self.graphicsView = QtWidgets.QGraphicsView(Dialog)
        self.graphicsView.setGeometry(QtCore.QRect(130, 10, 371, 221))
        self.graphicsView.setObjectName("graphicsView")
        self.radioButton = QtWidgets.QRadioButton(Dialog)
        self.radioButton.setGeometry(QtCore.QRect(20, 30, 82, 31))
        self.radioButton.setObjectName("radioButton")
        self.radioButton_2 = QtWidgets.QRadioButton(Dialog)
        self.radioButton_2.setGeometry(QtCore.QRect(20, 80, 82, 17))
        self.radioButton_2.setObjectName("radioButton_2")

        self.retranslateUi(Dialog)
        QtCore.QMetaObject.connectSlotsByName(Dialog)

    def retranslateUi(self, Dialog):
        _translate = QtCore.QCoreApplication.translate
        Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
        self.radioButton.setText(_translate("Dialog", "Generate"))
        self.radioButton_2.setText(_translate("Dialog", "Select"))

谢谢。

“选定的点将被返回” 的意思是什么? - eyllanesc
仅显示其坐标即可。 - Dàvid Nagy
我编辑了帖子,在那里放置了代码。谢谢您的回复。 - Dàvid Nagy
是的!我忘了回信。抱歉 :) 谢谢你的答复! - Dàvid Nagy
当然。这是我在这里的第一个问题。谢谢你提醒我。 - Dàvid Nagy
显示剩余2条评论
1个回答

8
QGraphicsView中添加了一个QGraphicsScene,每个场景管理着不同坐标系的系统。 QGraphicsView类似于相机,而QGraphicsScene类似于世界,当向场景中添加项时,它必须在其坐标系中。
如果您希望在单击时添加项,则最好重写QGraphicsScenemousePressEvent方法,并使用scenePos()方法获取相对于场景坐标系的位置。
另一件要做的事情是初始化属性setSceneRect(),该属性是QGraphicsView可以看到的空间。
建议如果使用多个按钮,请使用QButtonGroup将按钮映射,使信号易于处理。
class GraphicsScene(QGraphicsScene):
    def __init__(self, parent=None):
        QGraphicsScene.__init__(self, parent)
        self.setSceneRect(-100, -100, 200, 200)
        self.opt = ""

    def setOption(self, opt):
        self.opt = opt

    def mousePressEvent(self, event):
        pen = QPen(QtCore.Qt.black)
        brush = QBrush(QtCore.Qt.black)
        x = event.scenePos().x()
        y = event.scenePos().y()
        if self.opt == "Generate":
            self.addEllipse(x, y, 4, 4, pen, brush)
        elif self.opt == "Select":
            print(x, y)


class SimpleWindow(QtWidgets.QMainWindow, points.Ui_Dialog):
    def __init__(self, parent=None):
        super(SimpleWindow, self).__init__(parent)
        self.setupUi(self)

        self.scene = GraphicsScene(self)
        self.graphicsView.setScene(self.scene)
        self.graphicsView.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignTop)

        group = QButtonGroup(self)
        group.addButton(self.radioButton)
        group.addButton(self.radioButton_2)

        group.buttonClicked.connect(lambda btn: self.scene.setOption(btn.text()))
        self.radioButton.setChecked(True)
        self.scene.setOption(self.radioButton.text())

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接