代码之家  ›  专栏  ›  技术社区  ›  Dàvid Nagy

PyQt:QGraphicsView中的鼠标事件

  •  4
  • Dàvid Nagy  · 技术社区  · 7 年前

    我想用PyQt用Python编写一个简单的程序。

    使用两个单选按钮有两个选项:

    1. 用于选择点。这样,如果有人单击某个点,则会返回所选点。

    我对PyQt和GUI编程都是新手。我的主要问题是,我真的不明白鼠标事件在Qt中是如何工作的。

    我还附上了一张图片,以将问题形象化。 GUI

    我试图解决这个问题。为了放置小部件,我使用了Qt设计器,然后创建了一个名为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"))
    

    1 回复  |  直到 7 年前
        1
  •  6
  •   eyllanesc Yonghwan Shin    7 年前

    QGraphicsView QGraphicsScene 添加后,每一个都管理一个不同坐标系。这个 类似于摄像机和 与世界相似,当向场景中添加项目时,该项目必须位于其坐标系中。

    mousePressEvent 方法 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())