首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何将QGraphicsItems从场景绘制到QImage,而不需要在QGraphicsScene中更改它们?

如何将QGraphicsItems从场景绘制到QImage,而不需要在QGraphicsScene中更改它们?
EN

Stack Overflow用户
提问于 2020-06-18 09:21:24
回答 1查看 272关注 0票数 0

我正在把QGraphicsItem转换成在QGraphicsScene中的光栅化面具。我正在使用这些面具来进一步处理视频(取面具内的平均强度)。为了达到这个目的,我在一个QImage上一个一个地画场景中的每一个项目,它的大小刚好足以封住这个项目。一切正常,但场景中的物品消失了。这是因为当我在QImage上画笔时,我要把笔从项目中移除。当我完成时,我把原来的笔放回原处,但是这些东西不会再出现在现场。我如何“刷新”场景,使项目重新出现,或者,或者,防止项目完全消失?

我真的找不到任何遇到这个问题的人。所以也许我只是做了些根本错误的事。欢迎任何建议。

这是我的密码:

代码语言:javascript
运行
复制
class MyThread(QtCore.QThread):
    def __init__(self, scene):
        super().__init__()
        self.scene = scene

    def run(self):
        for item in self.scene.items():
            # Render the ROI item to create a rasterized mask.
            qimage = self.qimage_from_shape_item(item)
            # do some stuff

    @staticmethod
    def qimage_from_shape_item(item: QtWidgets.QAbstractGraphicsShapeItem) -> QtGui.QImage:
        # Get items pen and brush to set back later.
        pen = item.pen()
        brush = item.brush()
        # Remove pen, set brush to white.
        item.setPen(QtGui.QPen(QtCore.Qt.NoPen))
        item.setBrush(QtCore.Qt.white)

        # Determine the bounding box in pixel coordinates.
        top = int(item.scenePos().y() + item.boundingRect().top())
        left = int(item.scenePos().x() + item.boundingRect().left())
        bottom = int(item.scenePos().y() + item.boundingRect().bottom()) + 1
        right = int(item.scenePos().x() + item.boundingRect().right()) + 1

        size = QtCore.QSize(right - left, bottom - top)

        # Initialize qimage, use 8-bit grayscale.
        qimage = QtGui.QImage(size, QtGui.QImage.Format_Grayscale8)
        qimage.fill(QtCore.Qt.transparent)
        painter = QtGui.QPainter(qimage)

        painter.setRenderHint(QtGui.QPainter.Antialiasing)

        # Offset the painter to paint item in its correct pixel location.
        painter.translate(item.scenePos().x() - left, item.scenePos().y() - top)

        # Paint the item.
        item.paint(painter, QtWidgets.QStyleOptionGraphicsItem())

        # Set the pen and brush back.
        item.setPen(pen)
        item.setBrush(brush)

        # Set the pixel coordinate offset of the item to the QImage.
        qimage.setOffset(QtCore.QPoint(left, top))

        return qimage


if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)

    widget = QtWidgets.QWidget()
    layout = QtWidgets.QVBoxLayout(widget)

    view = QtWidgets.QGraphicsView()
    layout.addWidget(view)

    scene = QtWidgets.QGraphicsScene()
    view.setScene(scene)
    thread = MyThread(scene)

    view.setFixedSize(400, 300)
    scene.setSceneRect(0, 0, 400, 300)

    rect_item = QtWidgets.QGraphicsRectItem()

    p = QtCore.QPointF(123.4, 56.78)
    rect_item.setPos(p)

    r = QtCore.QRectF(0., 0., 161.8, 100.)
    rect_item.setRect(r)

    scene.addItem(rect_item)

    button = QtWidgets.QPushButton("Get masks")
    layout.addWidget(button)

    button.clicked.connect(thread.start)

    widget.show()

    sys.exit(app.exec_())
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-06-23 08:43:02

问题是,您“只能在主线程上创建和使用GUI小部件”,请参阅所以请回答这里中的更多信息。

我解决的方法是将GUI交互部分(即qimage_from_shape_item() )从线程中取出,并在主循环中处理它。我认为直接使用这些项目仍然不是很好,尽管暂时设置NoPen没有可见的闪烁效应或任何东西。

另一种选择可能是使用QGraphicsScene::render;但是,我不知道如何在不与场景中的其他项目交互的情况下逐个呈现项目。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62446623

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档