【问题标题】:Update the Opacity of QGraphicsItem更新 QGraphicsItem 的不透明度
【发布时间】:2019-06-04 12:58:56
【问题描述】:

我想在鼠标点击后更新一些 QGraphicsItem 的不透明度。正如其他解决方案所建议的那样,QGraphicScene 在鼠标按下事件后手动更新 GraphicsItem。我在 QGraphicsScene 和 QGraphicsItem 中尝试了不同的 setOpacity() 和 update()。但是没有一个有效,也不知道哪里出了问题。

import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *

CUBE_POS = {
    "a":(   8.281,  18.890),
    "b":(   8.668,  23.692),
    "c":(   21.493, 23.423),
    "d":(   21.24,  15.955),
    }        

class CubeItem(QGraphicsItem):

    def __init__(self, x, y, parent=None):
        super(CubeItem,self).__init__(parent)
        self.x = x
        self.y = y
        self.polygon = QPolygonF([
            QPointF(self.x-10, self.y-10), QPointF(self.x-10, self.y+10),
            QPointF(self.x+10, self.y+10), QPointF(self.x+10, self.y-10),
            ])
        self._painter = QPainter()

    ##Estimate the drawing area
    def boundingRect(self):
        return QRectF(self.x-10, self.y-10, 20, 20)

    ##Real Shape of drawing area
    def shape(self):
        path = QPainterPath()
        path.addRect(self.x-10, self.y-10, 20, 20)
        return path

    ##paint function called by graphicview
    def paint(self, painter, option, widget):
        painter.setBrush(Qt.red)
        painter.setOpacity(0.2)
        painter.drawRect(self.x-10, self.y-10, 20, 20)
        self._painter = painter

    def activate(self):
        try:
            #self._painter.setOpacity(1.0)
            self.setOpacity(1.0)
            self.update()
        except ValueError as e:
            print(e)

class TagScene(QGraphicsScene):

    def __init__(self, parent=None):
        super(TagScene, self).__init__(parent)

        self.cubes_items_ref = {}
        self.addCubes()

    def addCubes(self):
        for cube in CUBE_POS:
            newCube = CubeItem(CUBE_POS[cube][0]*15, 
                                   CUBE_POS[cube][1]*15)
            self.addItem(newCube)
            self.cubes_items_ref[cube] = newCube

    def mousePressEvent(self, event):
        print("mouse pressed")

        #for cube in self.cubes_items_ref:
        #    self.cubes_items_ref[cube].setOpacity(1.0)
        #    #self.cubes_items_ref[cube].activate()
        #self.update(QRectF(0,0,500,500))

        for cube in self.items():
            cube.setOpacity(1.0)
        self.update(QRectF(0,0,500,500))

class MainWindow(QMainWindow):

     def __init__(self):
        super(MainWindow, self).__init__()
        layout = QHBoxLayout()
        self.scene = TagScene()
        self.view = QGraphicsView(self.scene)
        self.scene.setSceneRect(QRectF(0,0,500,500))
        layout.addWidget(self.view)
        self.widget = QWidget()
        self.widget.setLayout(layout)
        self.setCentralWidget(self.widget)

if __name__ == "__main__":

    app = QApplication(sys.argv)
    test = MainWindow()
    test.show()
    sys.exit(app.exec_())

【问题讨论】:

    标签: python pyqt pyqt5 qgraphicsscene qgraphicsitem


    【解决方案1】:

    问题在于,当您覆盖 QGraphicsItem 的绘制方法时,您正在设置一个恒定的不透明度

    def paint(self, painter, option, widget):
        painter.setBrush(Qt.red)
        painter.setOpacity(0.2) # <-- this line is the problem
        painter.drawRect(self.x-10, self.y-10, 20, 20)
        self._painter = painter
    

    而且你不会使用 QPainter 已经通过 paint() 方法的不透明度。

    如果要设置初始不透明度,必须在构造函数中进行。另一方面,setOpacity() 方法已调用 update(),因此无需显式调用。

    import sys
    from PyQt5 import QtCore, QtGui, QtWidgets
    
    CUBE_POS = {
        "a": (8.281, 18.890),
        "b": (8.668, 23.692),
        "c": (21.493, 23.423),
        "d": (21.24, 15.955),
    }
    
    
    class CubeItem(QtWidgets.QGraphicsItem):
        def __init__(self, x, y, parent=None):
            super(CubeItem, self).__init__(parent)
            self.x = x
            self.y = y
            self.polygon = QtGui.QPolygonF(
                [
                    QtCore.QPointF(self.x - 10, self.y - 10),
                    QtCore.QPointF(self.x - 10, self.y + 10),
                    QtCore.QPointF(self.x + 10, self.y + 10),
                    QtCore.QPointF(self.x + 10, self.y - 10),
                ]
            )
            self.setOpacity(0.2) # initial opacity
    
        ##Estimate the drawing area
        def boundingRect(self):
            return QtCore.QRectF(self.x - 10, self.y - 10, 20, 20)
    
        ##Real Shape of drawing area
        def shape(self):
            path = QtGui.QPainterPath()
            path.addRect(self.boundingRect())
            return path
    
        ##paint function called by graphicview
        def paint(self, painter, option, widget):
            painter.setBrush(QtCore.Qt.red)
            painter.drawRect(self.x - 10, self.y - 10, 20, 20)
    
    
    class TagScene(QtWidgets.QGraphicsScene):
        def __init__(self, parent=None):
            super(TagScene, self).__init__(parent)
    
            self.cubes_items_ref = {}
            self.addCubes()
    
        def addCubes(self):
            for cube in CUBE_POS:
                newCube = CubeItem(CUBE_POS[cube][0] * 15, CUBE_POS[cube][1] * 15)
                self.addItem(newCube)
                self.cubes_items_ref[cube] = newCube
    
        def mousePressEvent(self, event):
            for cube in self.items():
                cube.setOpacity(1.0) # update opacity
    
    
    class MainWindow(QtWidgets.QMainWindow):
        def __init__(self):
            super(MainWindow, self).__init__()
            layout = QtWidgets.QHBoxLayout()
            self.scene = TagScene()
            self.view = QtWidgets.QGraphicsView(self.scene)
            self.scene.setSceneRect(QtCore.QRectF(0, 0, 500, 500))
            layout.addWidget(self.view)
            self.widget = QtWidgets.QWidget()
            self.widget.setLayout(layout)
            self.setCentralWidget(self.widget)
    
    
    if __name__ == "__main__":
    
        app = QtWidgets.QApplication(sys.argv)
        test = MainWindow()
        test.show()
        sys.exit(app.exec_())
    

    【讨论】:

    • 谢谢。有用。那么,这是否意味着paint() 中的painter 是静态的?
    • @S.H.我不知道你所说的静态是什么意思,但是 QPainter 是由 QGraphicsView 提供给项目的,默认情况下它会设置项目的通用属性,例如不透明度,所以如果你要使用现有的 QGraphicsItem 方法,那么你应该由于 QGraphicsView 已为您完成,因此无需手动设置。
    猜你喜欢
    • 1970-01-01
    • 2018-10-31
    • 2013-03-04
    • 2012-08-06
    • 2015-02-12
    • 1970-01-01
    • 2016-08-31
    • 2012-09-20
    • 1970-01-01
    相关资源
    最近更新 更多