【问题标题】:PyQt: Mouse events in QGraphicsViewPyQt:QGraphicsView 中的鼠标事件
【发布时间】:2018-03-05 01:28:47
【问题描述】:

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

我有一个 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"))

谢谢。

【问题讨论】:

  • 将返回选中的点是什么意思?
  • 显示它的坐标就够了。
  • 我建议您尝试解决它并告诉我们您尝试时遇到的问题。关于这个主题,互联网上有很多信息,就在 SO 中。
  • 我编辑了这篇文章。把代码放在那里。感谢您的回复。
  • 非常好解释这是什么不起作用,我还建议使用 QGraphicsScene 因为它返回有关场景的位置,这是您必须在项目中使用的位置。

标签: python pyqt pyqt5 qgraphicsview qgraphicsscene


【解决方案1】:

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())

【讨论】:

    猜你喜欢
    • 2011-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-25
    • 2016-06-22
    相关资源
    最近更新 更多