PyQt中QGraphicsView的鼠标事件

4

我正在尝试从QGraphicsView获取各种鼠标事件的坐标,但我不知道如何触发它们。最终,我想要向graphicsView添加一张图片,然后在其上面进行绘制。

理想情况下,我希望这些坐标的原点在左上角。

0,0--------------------
|
|
|
|
|
|
|          

test.py

import sys
from PyQt4 import QtCore, QtGui, uic


class test(QtGui.QMainWindow):

    def __init__(self):
        QtGui.QMainWindow.__init__(self)
        self.ui = uic.loadUi('test.ui', self)

        self.connect(self.ui.graphicsView, QtCore.SIGNAL("mousePressEvent()"), self.mouse_pressed)
        self.connect(self.ui.graphicsView, QtCore.SIGNAL("mouseMoveEvent()"), self.mouse_moved)
        self.connect(self.ui.graphicsView, QtCore.SIGNAL("mouseReleaseEvent()"), self.mouse_released)

        self.ui.show()

    def mouse_pressed(self):
        p = QtGui.QCursor.pos()
        print "pressed here: " + p.x() + ", " + p.y()

    def mouse_moved(self):
        p = QtGui.QCursor.pos()
        print "moved here: " + p.x() + ", " + p.y()

    def mouse_released(self):
        p = QtGui.QCursor.pos()
        print "released here: " + p.x() + ", " + p.y()


def main():
    app = QtGui.QApplication(sys.argv)
    ui = test()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

test.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>800</width>
    <height>600</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <layout class="QVBoxLayout" name="verticalLayout">
    <item>
     <widget class="QGraphicsView" name="graphicsView"/>
    </item>
   </layout>
  </widget>
  <widget class="QMenuBar" name="menubar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>800</width>
     <height>22</height>
    </rect>
   </property>
  </widget>
  <widget class="QStatusBar" name="statusbar"/>
 </widget>
 <resources/>
 <connections/>
</ui>

编辑:

这似乎有效。椭圆不再可移动,因为点击事件似乎接管了控制权。有什么想法吗?

import sys
from PyQt4 import QtCore, QtGui, uic


class graphicsScene(QtGui.QGraphicsScene):
    def __init__ (self, parent=None):
        super(graphicsScene, self).__init__ (parent)

    def mousePressEvent(self, event):
        position = QtCore.QPointF(event.scenePos())
        print "pressed here: " + str(position.x()) + ", " + str(position.y())
        self.update()

    def mouseMoveEvent(self, event):
        position = QtCore.QPointF(event.scenePos())
        print "moved here: " + str(position.x()) + ", " + str(position.y())
        self.update()

    def mouseReleaseEvent(self, event):
        position = QtCore.QPointF(event.scenePos())
        print "released here: " + str(position.x()) + ", " + str(position.y())
        self.update()


class test(QtGui.QMainWindow):

    def __init__(self):
        QtGui.QMainWindow.__init__(self)
        self.ui = uic.loadUi('test.ui', self)

        self.scene = graphicsScene()
        self.ui.graphicsView.setScene(self.scene)

        pen = QtGui.QPen(QtCore.Qt.red)
        brush = QtGui.QBrush(QtCore.Qt.blue)
        e = self.scene.addEllipse(10,10,100,100, pen, brush)
        e.setFlag(QtGui.QGraphicsItem.ItemIsMovable, True)

        self.ui.show()


def main():
    app = QtGui.QApplication(sys.argv)
    ui = test()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()
2个回答

3

mousePressEvent 和其他方法不是槽函数。你不能在这些方法上使用 connect。你需要在你的视图的 viewport() 上安装一个事件过滤器,并在你的小部件的 eventFilter 方法中捕获事件。

请参见事件过滤器


1
我认为你的意思是:在那些方法上你“不能”使用connect。而且,仅仅重载mousePressEvent()比安装事件过滤器更容易和更清晰。 - jmk
1
需要 OP 子类化 QGraphicsView 并在 UI 文件中将视图提升为此子类。这是一种过度复杂化的方法。如果想要更改视图的行为并在多个不同的地方重用该类,则子类化 QGraphicsView 是明智的选择。我假设在简单情况下不需要这样做。 - Pavel Strakhov
我想我按照你的建议做了。你有什么想法,为什么我的椭圆形着色不起作用? - waspinator
2
QColor.redQColor.blue 是函数。你需要使用 Qt.redQt.blue 枚举值。 - Pavel Strakhov
辉煌。最后一个问题,有没有简单的方法使椭圆可移动? - waspinator
我说谎了。另外,我该如何筛选仅为左键点击的鼠标单击事件呢?谢谢。 - waspinator

1
为了使椭圆形可移动,您需要将事件传递给父级。例如,在mouseMoveEvent中,您需要在方法末尾添加以下行:
super(graphicsScene, self).mouseMoveEvent(event)

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