【问题标题】:Not able to draw rectangel over Qgraphics image无法在 Qgraphics 图像上绘制矩形
【发布时间】:2018-09-13 15:11:51
【问题描述】:

我正在尝试在 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_())

【问题讨论】:

  • 嗨,Deepa,欢迎来到 Stack Overflow。我建议您查看How to ask 文档,以便提高收到答案的机会。特别要遵循这个建议keep track of what you find. Even if you don't find a useful answer elsewhere on the site, including links to related questions that haven't helped can help others in understanding how your question is different from the rest.

标签: python pyqt pyqt4 mouseevent qgraphicsview


【解决方案1】:

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

【讨论】:

  • 它正在按预期工作,谢谢..我还有一个相关的查询。我想将矩形放在视频上。我试图读取视频并将帧存储在一个文件夹中。现在我想按顺序读取文件夹,一个特定的帧绘制矩形,其余读取的帧应该保存矩形。我能够从视频中写入帧,但无法读取使用“os.listdi()”。你能帮我解决一下吗?
  • @Deepa 创建一个新问题,显示您已经尝试过什么,以及您失败了什么,我很乐意为您提供帮助,另一方面,最好的感谢方式是将我的答案标记为正确,如果您不知道如何操作,请查看tour
  • 感谢您的帮助...我将在我所做的工作中发布一个新问题..
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-22
  • 2020-05-08
  • 1970-01-01
相关资源
最近更新 更多