无法在Qgraphics图像上绘制rectangel

时间:2018-04-04 06:49:47

标签: python pyqt pyqt4 mouseevent qgraphicsview

我正在尝试在Qgraphics场景上绘制矩形。我找到了许多例子,但没有一个能为我工作。矩形在窗口中未被Qgraphics视图窗口小部件覆盖的区域上绘制,但是当我尝试覆盖图像时它不起作用。我不知道为什么。一个观察结果是Qgraphicsview鼠标释放事件没有被执行。但我无法解决这个问题。任何帮助都会有所帮助。提前谢谢。

我正在处理的代码如下所示。

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'zoom_win_qt.ui'
#
# Created by: PyQt4 UI code generator 4.11.4
#
# WARNING! All changes made in this file will be lost!

from PyQt4 import QtCore, QtGui
import numpy as np
from scipy.ndimage import zoom
import cv2
from matplotlib import pyplot as plt
try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    def _fromUtf8(s):
        return s

try:
    _encoding = QtGui.QApplication.UnicodeUTF8
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig)

class Ui_zoom_win_qt(object):
    def setupUi(self, zoom_win_qt):
        zoom_win_qt.setObjectName(_fromUtf8("zoom_win_qt"))
        zoom_win_qt.resize(800, 600)
        self.centralwidget = QtGui.QWidget(zoom_win_qt)
        self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
        self.graphicsView = QtGui.QGraphicsView(self.centralwidget)
        self.graphicsView.setGeometry(QtCore.QRect(80, 40, 611, 431))
        self.graphicsView.setObjectName(_fromUtf8("graphicsView"))        
        grview = self.graphicsView
        scene = QtGui.QGraphicsScene()
        pixmap = QtGui.QPixmap('Koala.jpg')
        pixmap = pixmap.scaledToHeight(420)
        scene.addPixmap(pixmap)        
        grview.setScene(scene)
        grview.show()        
        self.horizontalSlider = QtGui.QSlider(self.centralwidget)
        self.horizontalSlider.setGeometry(QtCore.QRect(80, 500, 160, 19))
        self.horizontalSlider.setOrientation(QtCore.Qt.Horizontal)
        self.horizontalSlider.setObjectName(_fromUtf8("horizontalSlider"))
        self.progressBar = QtGui.QProgressBar(self.centralwidget)
        self.progressBar.setGeometry(QtCore.QRect(590, 490, 118, 23))
        self.progressBar.setProperty("value", 24)
        self.progressBar.setObjectName(_fromUtf8("progressBar"))
        self.pushButton = QtGui.QPushButton(self.centralwidget)
        self.pushButton.setGeometry(QtCore.QRect(380, 500, 75, 23))
        self.pushButton.setObjectName(_fromUtf8("pushButton"))    

        self.pushButton.clicked.connect(test_clipped_zoom)  

        zoom_win_qt.setCentralWidget(self.centralwidget)
        self.menubar = QtGui.QMenuBar(zoom_win_qt)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 21))
        self.menubar.setObjectName(_fromUtf8("menubar"))
        zoom_win_qt.setMenuBar(self.menubar)
        self.statusbar = QtGui.QStatusBar(zoom_win_qt)
        self.statusbar.setObjectName(_fromUtf8("statusbar"))
        zoom_win_qt.setStatusBar(self.statusbar)

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

    def retranslateUi(self, zoom_win_qt):
        zoom_win_qt.setWindowTitle(_translate("zoom_win_qt", "MainWindow", None))
        self.pushButton.setText(_translate("zoom_win_qt", "PushButton", None))



class Myrect(QtGui.QMainWindow,Ui_zoom_win_qt):
    def __init__(self, *args, **kwargs):
        QtGui.QMainWindow.__init__(self, *args, **kwargs)
        self.setupUi(self)
        self.pos1 = [0,0]
        self.pos2 = [0,0]
        self.show()     


    def paintEvent(self, event):
        width = self.pos2[0]-self.pos1[0]
        height = self.pos2[1] - self.pos1[1]
        qp = QtGui.QPainter()        
        qp.begin(self)           
        qp.drawRect(self.pos1[0], self.pos1[1], width, height)        
        qp.end()

    def mousePressEvent(self, event):
        self.pos1[0], self.pos1[1] = event.pos().x(), event.pos().y()
        print("clicked")

    def mouseReleaseEvent(self, event):
        self.pos2[0], self.pos2[1] = event.pos().x(), event.pos().y()
        print("released")
        self.update()            






def test_clipped_zoom():
     zoom_win_qt.hide()
     w.show()




if __name__ == "__main__":
    import sys
    app = QtGui.QApplication(sys.argv)

    w = Myrect()
    zoom_win_qt = QtGui.QMainWindow()
    ui = Ui_zoom_win_qt()
    ui.setupUi(zoom_win_qt)
    zoom_win_qt.show()




    sys.exit(app.exec_())

1 个答案:

答案 0 :(得分:0)

QGraphicsView是一个显示场景(QGraphicsScene)的小部件,所以常见的是向场景中添加一个矩形(好像它是一个演员),而不是画画。您还在Myrect中绘制,这是其他小部件所在的小部件,因此它位于后台,其他小部件将覆盖您所做的绘画。

另一方面,不建议修改Qt Designer生成的类,因此我冒昧地将其恢复到初始状态

回到起点,要向QGraphicsScene添加一个矩形,你必须知道场景坐标系中这些点的坐标,所以一种方法是使用eventFilter() ,这必须过滤GraphicsSceneMousePressGraphicsSceneMouseRelease事件,这些事件具有位置,我们可以使用scenePos()方法获取它。

...
class Myrect(QtGui.QMainWindow,Ui_zoom_win_qt):
    def __init__(self, *args, **kwargs):
        QtGui.QMainWindow.__init__(self, *args, **kwargs)
        self.setupUi(self)   
        self.pushButton.clicked.connect(test_clipped_zoom)
        self.scene = QtGui.QGraphicsScene()
        pixmap = QtGui.QPixmap('Koala.jpg').scaledToHeight(420)
        self.scene.addPixmap(pixmap)        
        self.graphicsView.setScene(self.scene) 
        self.scene.installEventFilter(self)
        self.start = QtCore.QPointF()

    def eventFilter(self, obj, event):
        if obj == self.scene:
            if event.type() == QtCore.QEvent.GraphicsSceneMousePress:
                self.start = event.scenePos()
            elif event.type() == QtCore.QEvent.GraphicsSceneMouseRelease:
                end = event.scenePos()
                self.scene.addRect(QtCore.QRectF(self.start, end))
                self.start = QtCore.QPointF()
        return QtGui.QMainWindow.eventFilter(self, obj, event)


def test_clipped_zoom():
     zoom_win_qt.hide()
     w.show()

if __name__ == "__main__":
    import sys
    app = QtGui.QApplication(sys.argv)
    w = Myrect()
    w.show()
    sys.exit(app.exec_())

完整代码:

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'zoom_win_qt.ui'
#
# Created by: PyQt4 UI code generator 4.11.4
#
# WARNING! All changes made in this file will be lost!

from PyQt4 import QtCore, QtGui
try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    def _fromUtf8(s):
        return s

try:
    _encoding = QtGui.QApplication.UnicodeUTF8
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig)

class Ui_zoom_win_qt(object):
    def setupUi(self, zoom_win_qt):
        zoom_win_qt.setObjectName(_fromUtf8("zoom_win_qt"))
        zoom_win_qt.resize(800, 600)
        self.centralwidget = QtGui.QWidget(zoom_win_qt)
        self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
        self.graphicsView = QtGui.QGraphicsView(self.centralwidget)
        self.graphicsView.setGeometry(QtCore.QRect(80, 40, 611, 431))
        self.graphicsView.setObjectName(_fromUtf8("graphicsView"))             
        self.horizontalSlider = QtGui.QSlider(self.centralwidget)
        self.horizontalSlider.setGeometry(QtCore.QRect(80, 500, 160, 19))
        self.horizontalSlider.setOrientation(QtCore.Qt.Horizontal)
        self.horizontalSlider.setObjectName(_fromUtf8("horizontalSlider"))
        self.progressBar = QtGui.QProgressBar(self.centralwidget)
        self.progressBar.setGeometry(QtCore.QRect(590, 490, 118, 23))
        self.progressBar.setProperty("value", 24)
        self.progressBar.setObjectName(_fromUtf8("progressBar"))
        self.pushButton = QtGui.QPushButton(self.centralwidget)
        self.pushButton.setGeometry(QtCore.QRect(380, 500, 75, 23))
        self.pushButton.setObjectName(_fromUtf8("pushButton"))    
        zoom_win_qt.setCentralWidget(self.centralwidget)
        self.menubar = QtGui.QMenuBar(zoom_win_qt)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 21))
        self.menubar.setObjectName(_fromUtf8("menubar"))
        zoom_win_qt.setMenuBar(self.menubar)
        self.statusbar = QtGui.QStatusBar(zoom_win_qt)
        self.statusbar.setObjectName(_fromUtf8("statusbar"))
        zoom_win_qt.setStatusBar(self.statusbar)

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

    def retranslateUi(self, zoom_win_qt):
        zoom_win_qt.setWindowTitle(_translate("zoom_win_qt", "MainWindow", None))
        self.pushButton.setText(_translate("zoom_win_qt", "PushButton", None))



class Myrect(QtGui.QMainWindow,Ui_zoom_win_qt):
    def __init__(self, *args, **kwargs):
        QtGui.QMainWindow.__init__(self, *args, **kwargs)
        self.setupUi(self)   
        self.pushButton.clicked.connect(test_clipped_zoom)
        self.scene = QtGui.QGraphicsScene()
        pixmap = QtGui.QPixmap('Koala.jpg').scaledToHeight(420)
        self.scene.addPixmap(pixmap)        
        self.graphicsView.setScene(self.scene) 
        self.scene.installEventFilter(self)
        self.start = QtCore.QPointF()

    def eventFilter(self, obj, event):
        if obj == self.scene:
            if event.type() == QtCore.QEvent.GraphicsSceneMousePress:
                self.start = event.scenePos()
            elif event.type() == QtCore.QEvent.GraphicsSceneMouseRelease:
                end = event.scenePos()
                self.scene.addRect(QtCore.QRectF(self.start, end))
                self.start = QtCore.QPointF()
        return QtGui.QMainWindow.eventFilter(self, obj, event)


def test_clipped_zoom():
     zoom_win_qt.hide()
     w.show()

if __name__ == "__main__":
    import sys
    app = QtGui.QApplication(sys.argv)
    w = Myrect()
    w.show()
    sys.exit(app.exec_())