PyQt:QGraphicsView 中的鼠标事件 [英] PyQt: Mouse events in QGraphicsView

查看:365
本文介绍了PyQt:QGraphicsView 中的鼠标事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I would like to write a simple program in Python with PyQt.

我有一个 QGraphicsScene,我想执行以下操作:使用两个 RadioButtons 有 2 个选项:

I have a QGraphicsScene and I would like to do the following: There are 2 options using two RadioButtons:

  1. 用于生成点.这样,如果有人点击场景,就会出现一个椭圆.
  2. 用于选择点.这样,如果有人点击某个点,所选点将被返回.

我是 PyQt 和 GUI 编程的新手.我的主要问题是我不太了解鼠标事件在 Qt 中的工作原理.如果有人这么好心和耐心地向我解释鼠标事件的基础知识,并就上述问题给我一些提示,我将不胜感激.

I'm kinda new at PyQt and also at GUI programming. My main problem is that I don't really understand how mouse events work in Qt. If someone was so kind and patient to explain me the basics of mouse events and gave me some tipps for the problem explained above, I would be very grateful.

我也附上了一张图片,以可视化问题.

I attach a picture too, to visualize the problem.

我正试图解决这个问题.为了放置小部件,我使用了 Qt 设计器,然后创建了一个名为 SimpleWindow 的子类.

I was trying to do the problem. For placing the widgets I used the Qt Designer, and then created a subclass called 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"))

谢谢.

推荐答案

在一个 QGraphicsView 中添加了一个 QGraphicsScene ,每个管理一个不同坐标系.QGraphicsView 类似于相机,QGraphicsScene 类似于世界,当向场景中添加项目时,它必须在其坐标系中.

In a QGraphicsView a QGraphicsScene is added, each one manages a system of different coordinates. the QGraphicsView is similar to a camera and a QGraphicsScene is similar to the world, when one adds an item to the scene it must be in its coordinate system.

由于你想在点击时添加项目,最好覆盖QGraphicsScenemousePressEvent方法,并获取场景坐标中的位置使用了 scenePos() 方法.

As you want to add items when you click, it is better to overwrite the mousePressEvent method of QGraphicsScene, and get the position in the coordinates of the scene for which the scenePos() method is used.

另外要做的就是初始化属性setSceneRect(),也就是QGraphicsView可以看到的空间.

Another thing to do is to initialize the attribute setSceneRect() which is the space that QGraphicsView can see.

如果使用多个按钮,建议使用 QButtonGroup 映射按钮,以便轻松处理信号.

A recommendation if several buttons are used use a QButtonGroup that maps the buttons making easy the easy handling of the signals.

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

这篇关于PyQt:QGraphicsView 中的鼠标事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆